@openfeature/core
Version:
Shared OpenFeature JS components (server and web)
870 lines (833 loc) • 35.2 kB
TypeScript
type Metadata = Record<string, string>;
/**
* Defines where the library is intended to be run.
*/
type Paradigm = 'server' | 'client';
type PrimitiveValue = null | boolean | string | number;
type JsonObject = {
[key: string]: JsonValue;
};
type JsonArray = JsonValue[];
/**
* Represents a JSON node value.
*/
type JsonValue = PrimitiveValue | JsonObject | JsonArray;
type EvaluationContextValue = PrimitiveValue | Date | {
[key: string]: EvaluationContextValue;
} | EvaluationContextValue[];
/**
* A container for arbitrary contextual data that can be used as a basis for dynamic evaluation
*/
type EvaluationContext = {
/**
* A string uniquely identifying the subject (end-user, or client service) of a flag evaluation.
* Providers may require this field for fractional flag evaluation, rules, or overrides targeting specific users.
* Such providers may behave unpredictably if a targeting key is not specified at flag resolution.
*/
targetingKey?: string;
} & Record<string, EvaluationContextValue>;
interface ManageContext<T> {
/**
* Access the evaluation context set on the receiver.
* @returns {EvaluationContext} Evaluation context
*/
getContext(): EvaluationContext;
/**
* Sets evaluation context that will be used during flag evaluations
* on this receiver.
* @template T The type of the receiver
* @param {EvaluationContext} context Evaluation context
* @returns {T} The receiver (this object)
*/
setContext(context: EvaluationContext): T;
}
type FlagValueType = 'boolean' | 'string' | 'number' | 'object';
/**
* Represents a JSON node value.
*/
type FlagValue = boolean | string | number | JsonValue;
type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>);
/**
* A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
*
* This structure is populated by a provider for use by an Application Author (via the Evaluation API) or an Application Integrator (via hooks).
*/
type FlagMetadata = Record<string, string | number | boolean>;
type ResolutionDetails<U> = {
value: U;
variant?: string;
flagMetadata?: FlagMetadata;
reason?: ResolutionReason;
errorCode?: ErrorCode;
errorMessage?: string;
};
type EvaluationDetails<T extends FlagValue> = {
flagKey: string;
flagMetadata: Readonly<FlagMetadata>;
} & ResolutionDetails<T>;
declare const StandardResolutionReasons: {
/**
* The resolved value is static (no dynamic evaluation).
*/
readonly STATIC: "STATIC";
/**
* The resolved value was configured statically, or otherwise fell back to a pre-configured value.
*/
readonly DEFAULT: "DEFAULT";
/**
* The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.
*/
readonly TARGETING_MATCH: "TARGETING_MATCH";
/**
* The resolved value was the result of pseudorandom assignment.
*/
readonly SPLIT: "SPLIT";
/**
* The resolved value was retrieved from cache.
*/
readonly CACHED: "CACHED";
/**
* The resolved value was the result of the flag being disabled in the management system.
*/
readonly DISABLED: "DISABLED";
/**
* The reason for the resolved value could not be determined.
*/
readonly UNKNOWN: "UNKNOWN";
/**
* The resolved value is non-authoritative or possibly out of date.
*/
readonly STALE: "STALE";
/**
* The resolved value was the result of an error.
*
* Note: The `errorCode` and `errorMessage` fields may contain additional details of this error.
*/
readonly ERROR: "ERROR";
};
declare enum ErrorCode {
/**
* The value was resolved before the provider was ready.
*/
PROVIDER_NOT_READY = "PROVIDER_NOT_READY",
/**
* The provider has entered an irrecoverable error state.
*/
PROVIDER_FATAL = "PROVIDER_FATAL",
/**
* The flag could not be found.
*/
FLAG_NOT_FOUND = "FLAG_NOT_FOUND",
/**
* An error was encountered parsing data, such as a flag configuration.
*/
PARSE_ERROR = "PARSE_ERROR",
/**
* The type of the flag value does not match the expected type.
*/
TYPE_MISMATCH = "TYPE_MISMATCH",
/**
* The provider requires a targeting key and one was not provided in the evaluation context.
*/
TARGETING_KEY_MISSING = "TARGETING_KEY_MISSING",
/**
* The evaluation context does not meet provider requirements.
*/
INVALID_CONTEXT = "INVALID_CONTEXT",
/**
* An error with an unspecified code.
*/
GENERAL = "GENERAL"
}
interface Logger {
error(...args: unknown[]): void;
warn(...args: unknown[]): void;
info(...args: unknown[]): void;
debug(...args: unknown[]): void;
}
interface ManageLogger<T> {
/**
* Sets a logger on this receiver. This logger supersedes to the global logger
* and is passed to various components in the SDK.
* The logger configured on the global API object will be used for all evaluations,
* unless overridden in a particular client.
* @template T The type of the receiver
* @param {Logger} logger The logger to be used
* @returns {T} The receiver (this object)
*/
setLogger(logger: Logger): T;
}
declare class DefaultLogger implements Logger {
error(...args: unknown[]): void;
warn(...args: unknown[]): void;
info(): void;
debug(): void;
}
declare const LOG_LEVELS: Array<keyof Logger>;
declare class SafeLogger implements Logger {
private readonly logger;
private readonly fallbackLogger;
constructor(logger: Logger);
error(...args: unknown[]): void;
warn(...args: unknown[]): void;
info(...args: unknown[]): void;
debug(...args: unknown[]): void;
private log;
}
/**
* An enumeration of possible events for server-sdk providers.
*/
declare enum ServerProviderEvents {
/**
* The provider is ready to evaluate flags.
*/
Ready = "PROVIDER_READY",
/**
* The provider is in an error state.
*/
Error = "PROVIDER_ERROR",
/**
* The flag configuration in the source-of-truth has changed.
*/
ConfigurationChanged = "PROVIDER_CONFIGURATION_CHANGED",
/**
* The provider's cached state is no longer valid and may not be up-to-date with the source of truth.
*/
Stale = "PROVIDER_STALE"
}
/**
* An enumeration of possible events for web-sdk providers.
*/
declare enum ClientProviderEvents {
/**
* The provider is ready to evaluate flags.
*/
Ready = "PROVIDER_READY",
/**
* The provider is in an error state.
*/
Error = "PROVIDER_ERROR",
/**
* The flag configuration in the source-of-truth has changed.
*/
ConfigurationChanged = "PROVIDER_CONFIGURATION_CHANGED",
/**
* The context associated with the provider has changed, and the provider has reconciled it's associated state.
*/
ContextChanged = "PROVIDER_CONTEXT_CHANGED",
/**
* The context associated with the provider has changed, and the provider has not yet reconciled its associated state.
*/
Reconciling = "PROVIDER_RECONCILING",
/**
* The provider's cached state is no longer valid and may not be up-to-date with the source of truth.
*/
Stale = "PROVIDER_STALE"
}
/**
* A type representing any possible ProviderEvent (server or client side).
* In most cases, you probably want to import `ProviderEvents` from the respective SDK.
*/
type AnyProviderEvent = ServerProviderEvents | ClientProviderEvents;
type EventMetadata = {
[key: string]: string | boolean | number;
};
type CommonEventDetails = {
readonly providerName: string;
/**
* @deprecated alias of "domain", use domain instead
*/
readonly clientName?: string;
readonly domain?: string;
};
type CommonEventProps = {
readonly message?: string;
readonly metadata?: EventMetadata;
};
type ReadyEvent = CommonEventProps;
type ErrorEvent = CommonEventProps;
type StaleEvent = CommonEventProps;
type ReconcilingEvent = CommonEventProps & {
readonly errorCode: ErrorCode;
};
type ConfigChangeEvent = CommonEventProps & {
readonly flagsChanged?: string[];
};
type ServerEventMap = {
[ServerProviderEvents.Ready]: ReadyEvent;
[ServerProviderEvents.Error]: ErrorEvent;
[ServerProviderEvents.Stale]: StaleEvent;
[ServerProviderEvents.ConfigurationChanged]: ConfigChangeEvent;
};
type ClientEventMap = {
[ClientProviderEvents.Ready]: ReadyEvent;
[ClientProviderEvents.Error]: ErrorEvent;
[ClientProviderEvents.Stale]: StaleEvent;
[ClientProviderEvents.ConfigurationChanged]: ConfigChangeEvent;
[ClientProviderEvents.Reconciling]: CommonEventProps;
[ClientProviderEvents.ContextChanged]: CommonEventProps;
};
type ServerNotChangeEvents = ServerProviderEvents.Ready | ServerProviderEvents.Error | ServerProviderEvents.Stale;
type ClientNotChangeEvents = ClientProviderEvents.Ready | ClientProviderEvents.Error | ClientProviderEvents.Stale | ClientProviderEvents.ContextChanged | ClientProviderEvents.Reconciling;
type NotChangeEvents = ServerNotChangeEvents | ClientNotChangeEvents;
type EventContext<U extends Record<string, unknown> = Record<string, unknown>, T extends ServerProviderEvents | ClientProviderEvents = ServerProviderEvents | ClientProviderEvents> = (T extends ClientProviderEvents ? ClientEventMap[T] : T extends ServerProviderEvents ? ServerEventMap[T] : never) & U;
type EventDetails<T extends ServerProviderEvents | ClientProviderEvents = ServerProviderEvents | ClientProviderEvents> = EventContext<Record<string, unknown>, T> & CommonEventDetails;
type EventHandler<T extends ServerProviderEvents | ClientProviderEvents = ServerProviderEvents | ClientProviderEvents> = (eventDetails?: EventDetails<T>) => Promise<unknown> | unknown;
type EventOptions = {
signal?: AbortSignal;
};
interface Eventing<T extends ServerProviderEvents | ClientProviderEvents> {
/**
* Adds a handler for the given provider event type.
* The handlers are called in the order they have been added.
* @param eventType The provider event type to listen to
* @param {EventHandler} handler The handler to run on occurrence of the event type
* @param {EventOptions} options Optional options such as signal for aborting
*/
addHandler(eventType: T extends ClientProviderEvents ? ClientProviderEvents.ConfigurationChanged : ServerProviderEvents.ConfigurationChanged, handler: EventHandler<T extends ClientProviderEvents ? ClientProviderEvents.ConfigurationChanged : ServerProviderEvents.ConfigurationChanged>, options?: EventOptions): void;
addHandler(eventType: T extends ClientProviderEvents ? ClientNotChangeEvents : ServerNotChangeEvents, handler: EventHandler<T extends ClientProviderEvents ? ClientNotChangeEvents : ServerNotChangeEvents>, options?: EventOptions): void;
addHandler(eventType: T extends ClientProviderEvents ? ClientProviderEvents : ServerProviderEvents, handler: EventHandler<T extends ClientProviderEvents ? ClientProviderEvents : ServerProviderEvents>, options?: EventOptions): void;
/**
* Removes a handler for the given provider event type.
* @param {AnyProviderEvent} eventType The provider event type to remove the listener for
* @param {EventHandler} handler The handler to remove for the provider event type
*/
removeHandler(eventType: T, handler: EventHandler<T>): void;
/**
* Gets the current handlers for the given provider event type.
* @param {AnyProviderEvent} eventType The provider event type to get the current handlers for
* @returns {EventHandler[]} The handlers currently attached to the given provider event type
*/
getHandlers(eventType: T): EventHandler<T>[];
}
/**
* Event emitter to be optionally implemented by providers.
* Implemented by @see OpenFeatureEventEmitter.
*/
interface ProviderEventEmitter<E extends AnyProviderEvent, AdditionalContext extends Record<string, unknown> = Record<string, unknown>> extends ManageLogger<ProviderEventEmitter<E, AdditionalContext>> {
emit(eventType: E, context?: EventContext): void;
addHandler(eventType: AnyProviderEvent, handler: EventHandler): void;
removeHandler(eventType: AnyProviderEvent, handler: EventHandler): void;
removeAllHandlers(eventType?: AnyProviderEvent): void;
getHandlers(eventType: AnyProviderEvent): EventHandler[];
}
/**
* Returns true if the provider's status corresponds to the event.
* If the provider's status is not defined, it matches READY.
* @param {AnyProviderEvent} event event to match
* @param {ClientProviderStatus | ServerProviderStatus} status status of provider
* @returns {boolean} boolean indicating if the provider status corresponds to the event.
*/
declare const statusMatchesEvent: <T extends AnyProviderEvent>(event: T, status?: ClientProviderStatus | ServerProviderStatus) => boolean;
/**
* The GenericEventEmitter should only be used within the SDK. It supports additional properties that can be included
* in the event details.
*/
declare abstract class GenericEventEmitter<E extends AnyProviderEvent, AdditionalContext extends Record<string, unknown> = Record<string, unknown>> implements ProviderEventEmitter<E>, ManageLogger<GenericEventEmitter<E, AdditionalContext>> {
private readonly globalLogger?;
protected abstract readonly eventEmitter: PlatformEventEmitter;
private readonly _handlers;
private _eventLogger?;
constructor(globalLogger?: (() => Logger) | undefined);
emit(eventType: E, context?: EventContext): void;
addHandler(eventType: AnyProviderEvent, handler: EventHandler): void;
removeHandler(eventType: AnyProviderEvent, handler: EventHandler): void;
removeAllHandlers(eventType?: AnyProviderEvent): void;
getHandlers(eventType: AnyProviderEvent): EventHandler[];
setLogger(logger: Logger): this;
protected get _logger(): Logger | undefined;
}
/**
* This is an un-exported type that corresponds to NodeJS.EventEmitter.
* We can't use that type here, because this module is used in both the browser, and the server.
* In the server, node (or whatever server runtime) provides an implementation for this.
* In the browser, we bundle in the popular 'EventEmitter3' package, which is a polyfill of NodeJS.EventEmitter.
*/
interface PlatformEventEmitter {
addListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
on(eventName: string | symbol, listener: (...args: any[]) => void): this;
once(eventName: string | symbol, listener: (...args: any[]) => void): this;
removeListener(eventName: string | symbol, listener: (...args: any[]) => void): this;
off(eventName: string | symbol, listener: (...args: any[]) => void): this;
removeAllListeners(event?: string | symbol): this;
listeners(eventName: string | symbol): Function[];
emit(eventName: string | symbol, ...args: any[]): boolean;
listenerCount(eventName: string | symbol, listener?: Function): number;
eventNames(): Array<string | symbol>;
}
type TrackingEventValue = PrimitiveValue | Date | {
[key: string]: TrackingEventValue;
} | TrackingEventValue[];
/**
* A container for arbitrary data that can relevant to tracking events.
*/
type TrackingEventDetails = {
/**
* A numeric value associated with this event.
*/
value?: number;
} & Record<string, TrackingEventValue>;
/**
* The state of the provider.
* Note that the provider's state is handled by the SDK.
*/
declare enum ServerProviderStatus {
/**
* The provider has not been initialized and cannot yet evaluate flags.
*/
NOT_READY = "NOT_READY",
/**
* The provider is ready to resolve flags.
*/
READY = "READY",
/**
* 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",
/**
* The provider has entered an irrecoverable error state.
*/
FATAL = "FATAL"
}
/**
* The state of the provider.
* Note that the provider's state is handled by the SDK.
*/
declare enum ClientProviderStatus {
/**
* The provider has not been initialized and cannot yet evaluate flags.
*/
NOT_READY = "NOT_READY",
/**
* The provider is ready to resolve flags.
*/
READY = "READY",
/**
* 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",
/**
* The provider has entered an irrecoverable error state.
*/
FATAL = "FATAL",
/**
* The provider is reconciling its state with a context change.
*/
RECONCILING = "RECONCILING"
}
/**
* Static data about the provider.
*/
interface ProviderMetadata extends Readonly<Metadata> {
readonly name: string;
}
interface CommonProvider<S extends ClientProviderStatus | ServerProviderStatus> {
readonly metadata: ProviderMetadata;
/**
* Represents where the provider is intended to be run. If defined,
* the SDK will enforce that the defined paradigm at runtime.
*/
readonly runsOn?: Paradigm;
/**
* @deprecated the SDK now maintains the provider's state; there's no need for providers to implement this field.
* Returns a representation of the current readiness of the provider.
*
* _Providers which do not implement this method are assumed to be ready immediately._
*/
readonly status?: S;
/**
* An event emitter for ProviderEvents.
* @see ProviderEvents
*/
events?: ProviderEventEmitter<AnyProviderEvent>;
/**
* A function used to shut down the provider.
* Called when this provider is replaced with a new one, or when the OpenFeature is shut down.
*/
onClose?(): Promise<void>;
/**
* A function used to setup the provider.
* Called by the SDK after the provider is set if the provider's status is NOT_READY.
* When the returned promise resolves, the SDK fires the ProviderEvents.Ready event.
* If the returned promise rejects, the SDK fires the ProviderEvents.Error event.
* Use this function to perform any context-dependent setup within the provider.
* @param context
*/
initialize?(context?: EvaluationContext): Promise<void>;
/**
* Track a user action or application state, usually representing a business objective or outcome.
* @param trackingEventName
* @param context
* @param trackingEventDetails
*/
track?(trackingEventName: string, context: EvaluationContext, trackingEventDetails: TrackingEventDetails): void;
}
interface ClientMetadata {
/**
* @deprecated alias of "domain", use domain instead
*/
readonly name?: string;
readonly domain?: string;
readonly version?: string;
readonly providerMetadata: ProviderMetadata;
}
type HookHints = Readonly<Record<string, unknown>>;
interface HookContext<T extends FlagValue = FlagValue> {
readonly flagKey: string;
readonly defaultValue: T;
readonly flagValueType: FlagValueType;
readonly context: Readonly<EvaluationContext>;
readonly clientMetadata: ClientMetadata;
readonly providerMetadata: ProviderMetadata;
readonly logger: Logger;
}
interface BeforeHookContext extends HookContext {
context: EvaluationContext;
}
interface BaseHook<T extends FlagValue = FlagValue, BeforeHookReturn = unknown, HooksReturn = unknown> {
/**
* Runs before flag values are resolved from the provider.
* If an EvaluationContext is returned, it will be merged with the pre-existing EvaluationContext.
* @param hookContext
* @param hookHints
*/
before?(hookContext: BeforeHookContext, hookHints?: HookHints): BeforeHookReturn;
/**
* Runs after flag values are successfully resolved from the provider.
* @param hookContext
* @param evaluationDetails
* @param hookHints
*/
after?(hookContext: Readonly<HookContext<T>>, evaluationDetails: EvaluationDetails<T>, hookHints?: HookHints): HooksReturn;
/**
* Runs in the event of an unhandled error or promise rejection during flag resolution, or any attached hooks.
* @param hookContext
* @param error
* @param hookHints
*/
error?(hookContext: Readonly<HookContext<T>>, error: unknown, hookHints?: HookHints): HooksReturn;
/**
* Runs after all other hook stages, regardless of success or error.
* @param hookContext
* @param evaluationDetails
* @param hookHints
*/
finally?(hookContext: Readonly<HookContext<T>>, evaluationDetails: EvaluationDetails<T>, hookHints?: HookHints): HooksReturn;
}
interface EvaluationLifeCycle<T> {
/**
* Adds hooks that will run during flag evaluations on this receiver.
* Hooks are executed in the order they were registered. Adding additional hooks
* will not remove existing hooks.
* Hooks registered on the global API object run with all evaluations.
* Hooks registered on the client run with all evaluations on that client.
* @template T The type of the receiver
* @param {BaseHook[]} hooks A list of hooks that should always run
* @returns {T} The receiver (this object)
*/
addHooks(...hooks: BaseHook[]): T;
/**
* Access all the hooks that are registered on this receiver.
* @returns {BaseHook[]} A list of the client hooks
*/
getHooks(): BaseHook[];
/**
* Clears all the hooks that are registered on this receiver.
* @template T The type of the receiver
* @returns {T} The receiver (this object)
*/
clearHooks(): T;
}
/**
* Error Options were added in ES2022. Manually adding the type so that an
* earlier target can be used.
*/
type ErrorOptions = {
cause?: unknown;
};
declare abstract class OpenFeatureError extends Error {
abstract code: ErrorCode;
cause?: unknown;
constructor(message?: string, options?: ErrorOptions);
}
declare class FlagNotFoundError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class GeneralError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class InvalidContextError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class ParseError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class ProviderFatalError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class ProviderNotReadyError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class TargetingKeyMissingError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare class TypeMismatchError extends OpenFeatureError {
code: ErrorCode;
constructor(message?: string, options?: ErrorOptions);
}
declare const instantiateErrorByErrorCode: (errorCode: ErrorCode, message?: string) => OpenFeatureError;
/**
* The attributes of an OpenTelemetry compliant event for flag evaluation.
* @see https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-logs/
*/
declare const TelemetryAttribute: {
/**
* The lookup key of the feature flag.
*
* - type: `string`
* - requirement level: `required`
* - example: `logo-color`
*/
readonly KEY: "feature_flag.key";
/**
* Describes a class of error the operation ended with.
*
* - type: `string`
* - requirement level: `conditionally required`
* - condition: `reason` is `error`
* - example: `flag_not_found`
*/
readonly ERROR_CODE: "error.type";
/**
* A message explaining the nature of an error occurring during flag evaluation.
*
* - type: `string`
* - requirement level: `recommended`
* - example: `Flag not found`
*/
readonly ERROR_MESSAGE: "error.message";
/**
* A semantic identifier for an evaluated flag value.
*
* - type: `string`
* - requirement level: `conditionally required`
* - condition: variant is defined on the evaluation details
* - example: `blue`; `on`; `true`
*/
readonly VARIANT: "feature_flag.result.variant";
/**
* The evaluated value of the feature flag.
*
* - type: `undefined`
* - requirement level: `conditionally required`
* - condition: variant is not defined on the evaluation details
* - example: `#ff0000`; `1`; `true`
*/
readonly VALUE: "feature_flag.result.value";
/**
* The unique identifier for the flag evaluation context. For example, the targeting key.
*
* - type: `string`
* - requirement level: `recommended`
* - example: `5157782b-2203-4c80-a857-dbbd5e7761db`
*/
readonly CONTEXT_ID: "feature_flag.context.id";
/**
* The reason code which shows how a feature flag value was determined.
*
* - type: `string`
* - requirement level: `recommended`
* - example: `targeting_match`
*/
readonly REASON: "feature_flag.result.reason";
/**
* Describes a class of error the operation ended with.
*
* - type: `string`
* - requirement level: `recommended`
* - example: `flag_not_found`
*/
readonly PROVIDER: "feature_flag.provider.name";
/**
* The identifier of the flag set to which the feature flag belongs.
*
* - type: `string`
* - requirement level: `recommended`
* - example: `proj-1`; `ab98sgs`; `service1/dev`
*/
readonly FLAG_SET_ID: "feature_flag.set.id";
/**
* The version of the ruleset used during the evaluation. This may be any stable value which uniquely identifies the ruleset.
*
* - type: `string`
* - requirement level: `recommended`
* - example: `1.0.0`; `2021-01-01`
*/
readonly VERSION: "feature_flag.version";
};
/**
* Well-known flag metadata attributes for telemetry events.
* @see https://openfeature.dev/specification/appendix-d#flag-metadata
*/
declare const TelemetryFlagMetadata: {
/**
* The context identifier returned in the flag metadata uniquely identifies
* the subject of the flag evaluation. If not available, the targeting key
* should be used.
*/
readonly CONTEXT_ID: "contextId";
/**
* A logical identifier for the flag set.
*/
readonly FLAG_SET_ID: "flagSetId";
/**
* A version string (format unspecified) for the flag or flag set.
*/
readonly VERSION: "version";
};
type EvaluationEvent = {
/**
* The name of the feature flag evaluation event.
*/
name: string;
/**
* The attributes of an OpenTelemetry compliant event for flag evaluation.
* @experimental The attributes are subject to change.
* @see https://opentelemetry.io/docs/specs/semconv/feature-flags/feature-flags-logs/
*/
attributes: Record<string, string | number | boolean | FlagValue>;
};
/**
* Returns an OpenTelemetry compliant event for flag evaluation.
* @param {HookContext} hookContext Contextual information about the flag evaluation
* @param {EvaluationDetails} evaluationDetails The details of the flag evaluation
* @returns {EvaluationEvent} An evaluation event object containing the event name and attributes
*/
declare function createEvaluationEvent(hookContext: Readonly<HookContext<FlagValue>>, evaluationDetails: EvaluationDetails<FlagValue>): EvaluationEvent;
/**
* Checks whether the parameter is a string.
* @param {unknown} value The value to check
* @returns {value is string} True if the value is a string
*/
declare function isString(value: unknown): value is string;
/**
* Returns the parameter if it is a string, otherwise returns undefined.
* @param {unknown} value The value to check
* @returns {string|undefined} The parameter if it is a string, otherwise undefined
*/
declare function stringOrUndefined(value: unknown): string | undefined;
/**
* Checks whether the parameter is an object.
* @param {unknown} value The value to check
* @returns {value is string} True if the value is an object
*/
declare function isObject<T extends object>(value: unknown): value is T;
/**
* Returns the parameter if it is an object, otherwise returns undefined.
* @param {unknown} value The value to check
* @returns {object|undefined} The parameter if it is an object, otherwise undefined
*/
declare function objectOrUndefined<T extends object>(value: unknown): T | undefined;
type AnyProviderStatus = ClientProviderStatus | ServerProviderStatus;
/**
* A provider and its current status.
* For internal use only.
*/
declare class ProviderWrapper<P extends CommonProvider<AnyProviderStatus>, S extends AnyProviderStatus> {
private _provider;
private _status;
private _pendingContextChanges;
constructor(_provider: P, _status: S, _statusEnumType: typeof ClientProviderStatus | typeof ServerProviderStatus);
get provider(): P;
set provider(provider: P);
get status(): S;
set status(status: S);
get allContextChangesSettled(): boolean;
incrementPendingContextChanges(): void;
decrementPendingContextChanges(): void;
}
declare abstract class OpenFeatureCommonAPI<S extends AnyProviderStatus, P extends CommonProvider<S> = CommonProvider<S>, H extends BaseHook = BaseHook> implements Eventing<AnyProviderEvent>, EvaluationLifeCycle<OpenFeatureCommonAPI<S, P>>, ManageLogger<OpenFeatureCommonAPI<S, P>> {
protected abstract readonly _statusEnumType: typeof ClientProviderStatus | typeof ServerProviderStatus;
protected abstract _createEventEmitter(): GenericEventEmitter<AnyProviderEvent>;
protected abstract _defaultProvider: ProviderWrapper<P, AnyProviderStatus>;
protected abstract readonly _domainScopedProviders: Map<string, ProviderWrapper<P, AnyProviderStatus>>;
protected abstract readonly _apiEmitter: GenericEventEmitter<AnyProviderEvent>;
protected _hooks: H[];
protected _context: EvaluationContext;
protected _logger: Logger;
private readonly _clientEventHandlers;
protected _domainScopedContext: Map<string, EvaluationContext>;
protected _clientEvents: Map<string | undefined, GenericEventEmitter<AnyProviderEvent>>;
protected _runsOn: Paradigm;
constructor(category: Paradigm);
addHooks(...hooks: H[]): this;
getHooks(): H[];
clearHooks(): this;
setLogger(logger: Logger): this;
/**
* Get metadata about the default provider.
* @returns {ProviderMetadata} Provider Metadata
*/
get providerMetadata(): ProviderMetadata;
/**
* Get metadata about a registered provider using the client name.
* An unbound or empty client name will return metadata from the default provider.
* @param {string} domain An identifier which logically binds clients with providers
* @returns {ProviderMetadata} Provider Metadata
*/
getProviderMetadata(domain?: string): ProviderMetadata;
/**
* Adds a handler for the given provider event type.
* The handlers are called in the order they have been added.
* API (global) events run for all providers.
* @param {AnyProviderEvent} eventType The provider event type to listen to
* @param {EventHandler} handler The handler to run on occurrence of the event type
* @param {EventOptions} options Optional options such as signal for aborting
*/
addHandler<T extends AnyProviderEvent>(eventType: T, handler: EventHandler, options?: EventOptions): void;
/**
* Removes a handler for the given provider event type.
* @param {AnyProviderEvent} eventType The provider event type to remove the listener for
* @param {EventHandler} handler The handler to remove for the provider event type
*/
removeHandler<T extends AnyProviderEvent>(eventType: T, handler: EventHandler): void;
/**
* Removes all event handlers.
*/
clearHandlers(): void;
/**
* Gets the current handlers for the given provider event type.
* @param {AnyProviderEvent} eventType The provider event type to get the current handlers for
* @returns {EventHandler[]} The handlers currently attached to the given provider event type
*/
getHandlers<T extends AnyProviderEvent>(eventType: T): EventHandler[];
abstract setProviderAndWait(clientOrProvider?: string | P, providerContextOrUndefined?: P | EvaluationContext, contextOrUndefined?: EvaluationContext): Promise<void>;
abstract setProvider(clientOrProvider?: string | P, providerContextOrUndefined?: P | EvaluationContext, contextOrUndefined?: EvaluationContext): this;
protected setAwaitableProvider(domainOrProvider?: string | P, providerOrUndefined?: P): Promise<void> | void;
protected getProviderForClient(domain?: string): P;
protected buildAndCacheEventEmitterForClient(domain?: string): GenericEventEmitter<AnyProviderEvent>;
private getUnboundEmitters;
protected getAssociatedEventEmitters(domain: string | undefined): GenericEventEmitter<AnyProviderEvent, Record<string, unknown>>[];
private transferListeners;
close(): Promise<void>;
protected clearProvidersAndSetDefault(defaultProvider: P): Promise<void>;
private get allProviders();
private handleShutdownError;
}
export { ClientProviderEvents as AllProviderEvents, ClientProviderStatus as AllProviderStatus, ClientProviderEvents, ClientProviderStatus, DefaultLogger, ErrorCode, FlagNotFoundError, GeneralError, GenericEventEmitter, InvalidContextError, LOG_LEVELS, OpenFeatureCommonAPI, OpenFeatureError, ParseError, ProviderFatalError, ProviderNotReadyError, ProviderWrapper, SafeLogger, ServerProviderEvents, ServerProviderStatus, StandardResolutionReasons, TargetingKeyMissingError, TelemetryAttribute, TelemetryFlagMetadata, TypeMismatchError, createEvaluationEvent, instantiateErrorByErrorCode, isObject, isString, objectOrUndefined, statusMatchesEvent, stringOrUndefined };
export type { AnyProviderEvent, BaseHook, BeforeHookContext, ClientMetadata, CommonEventDetails, CommonProvider, ConfigChangeEvent, ErrorEvent, EvaluationContext, EvaluationContextValue, EvaluationDetails, EvaluationLifeCycle, EventContext, EventDetails, EventHandler, EventMetadata, EventOptions, Eventing, FlagMetadata, FlagValue, FlagValueType, HookContext, HookHints, JsonArray, JsonObject, JsonValue, Logger, ManageContext, ManageLogger, Metadata, NotChangeEvents, Paradigm, PrimitiveValue, ProviderEventEmitter, ProviderMetadata, ReadyEvent, ReconcilingEvent, ResolutionDetails, ResolutionReason, StaleEvent, TrackingEventDetails, TrackingEventValue };