@openfeature/web-sdk 0.3.6-experimental → 0.3.8-experimental

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -1,13 +1,47 @@
1
+ declare enum ProviderEvents {
2
+ /**
3
+ * The provider is ready to evaluate flags.
4
+ */
5
+ Ready = "PROVIDER_READY",
6
+ /**
7
+ * The provider is in an error state.
8
+ */
9
+ Error = "PROVIDER_ERROR",
10
+ /**
11
+ * The flag configuration in the source-of-truth has changed.
12
+ */
13
+ ConfigurationChanged = "PROVIDER_CONFIGURATION_CHANGED",
14
+ /**
15
+ * The provider's cached state is no longer valid and may not be up-to-date with the source of truth.
16
+ */
17
+ Stale = "PROVIDER_STALE"
18
+ }
19
+
1
20
  type EventMetadata = {
2
21
  [key: string]: string | boolean | number;
3
22
  };
4
- type EventDetails = {
23
+ type CommonEventDetails = {
5
24
  clientName?: string;
25
+ };
26
+ type CommonEventProps = {
6
27
  message?: string;
7
- flagsChanged?: string[];
8
28
  metadata?: EventMetadata;
9
29
  };
10
- type EventHandler = (eventDetails?: EventDetails) => Promise<unknown> | unknown;
30
+ type ReadyEvent = CommonEventProps;
31
+ type ErrorEvent = CommonEventProps;
32
+ type StaleEvent = CommonEventProps;
33
+ type ConfigChangeEvent = CommonEventProps & {
34
+ flagsChanged?: string[];
35
+ };
36
+ type EventMap = {
37
+ [ProviderEvents.Ready]: ReadyEvent;
38
+ [ProviderEvents.Error]: ErrorEvent;
39
+ [ProviderEvents.Stale]: StaleEvent;
40
+ [ProviderEvents.ConfigurationChanged]: ConfigChangeEvent;
41
+ };
42
+ type EventContext<T extends ProviderEvents, U extends Record<string, unknown> = Record<string, unknown>> = EventMap[T] & U;
43
+ type EventDetails<T extends ProviderEvents> = EventContext<T> & CommonEventDetails;
44
+ type EventHandler<T extends ProviderEvents> = (eventDetails?: EventDetails<T>) => Promise<unknown> | unknown;
11
45
  interface Eventing {
12
46
  /**
13
47
  * Adds a handler for the given provider event type.
@@ -15,53 +49,94 @@ interface Eventing {
15
49
  * @param {ProviderEvents} eventType The provider event type to listen to
16
50
  * @param {EventHandler} handler The handler to run on occurrence of the event type
17
51
  */
18
- addHandler(eventType: ProviderEvents, handler: EventHandler): void;
52
+ addHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
19
53
  /**
20
54
  * Removes a handler for the given provider event type.
21
55
  * @param {ProviderEvents} eventType The provider event type to remove the listener for
22
56
  * @param {EventHandler} handler The handler to remove for the provider event type
23
57
  */
24
- removeHandler(eventType: ProviderEvents, handler: EventHandler): void;
58
+ removeHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
25
59
  /**
26
60
  * Gets the current handlers for the given provider event type.
27
61
  * @param {ProviderEvents} eventType The provider event type to get the current handlers for
28
62
  * @returns {EventHandler[]} The handlers currently attached to the given provider event type
29
63
  */
30
- getHandlers(eventType: ProviderEvents): EventHandler[];
64
+ getHandlers<T extends ProviderEvents>(eventType: T): EventHandler<T>[];
31
65
  }
32
- declare enum ProviderEvents {
33
- /**
34
- * The provider is ready to evaluate flags.
35
- */
36
- Ready = "PROVIDER_READY",
37
- /**
38
- * The provider is in an error state.
39
- */
40
- Error = "PROVIDER_ERROR",
41
- /**
42
- * The flag configuration in the source-of-truth has changed.
43
- */
44
- ConfigurationChanged = "PROVIDER_CONFIGURATION_CHANGED",
66
+
67
+ interface Logger {
68
+ error(...args: unknown[]): void;
69
+ warn(...args: unknown[]): void;
70
+ info(...args: unknown[]): void;
71
+ debug(...args: unknown[]): void;
72
+ }
73
+ interface ManageLogger<T> {
45
74
  /**
46
- * The provider's cached state is no longer valid and may not be up-to-date with the source of truth.
75
+ * Sets a logger on this receiver. This logger supersedes to the global logger
76
+ * and is passed to various components in the SDK.
77
+ * The logger configured on the global API object will be used for all evaluations,
78
+ * unless overridden in a particular client.
79
+ * @template T The type of the receiver
80
+ * @param {Logger} logger The logger to be used
81
+ * @returns {T} The receiver (this object)
47
82
  */
48
- Stale = "PROVIDER_STALE"
83
+ setLogger(logger: Logger): T;
49
84
  }
50
- declare class OpenFeatureEventEmitter implements ManageLogger<OpenFeatureEventEmitter> {
85
+
86
+ declare class DefaultLogger implements Logger {
87
+ error(...args: unknown[]): void;
88
+ warn(...args: unknown[]): void;
89
+ info(): void;
90
+ debug(): void;
91
+ }
92
+
93
+ declare const LOG_LEVELS: Array<keyof Logger>;
94
+ declare class SafeLogger implements Logger {
95
+ private readonly logger;
96
+ private readonly fallbackLogger;
97
+ constructor(logger: Logger);
98
+ error(...args: unknown[]): void;
99
+ warn(...args: unknown[]): void;
100
+ info(...args: unknown[]): void;
101
+ debug(...args: unknown[]): void;
102
+ private log;
103
+ }
104
+
105
+ declare abstract class GenericEventEmitter<AdditionalContext extends Record<string, unknown> = Record<string, unknown>> implements ManageLogger<GenericEventEmitter<AdditionalContext>> {
51
106
  private readonly globalLogger?;
52
107
  private readonly _handlers;
53
108
  private readonly eventEmitter;
54
109
  private _eventLogger?;
55
110
  constructor(globalLogger?: (() => Logger) | undefined);
56
- emit(eventType: ProviderEvents, context?: EventDetails): void;
57
- addHandler(eventType: ProviderEvents, handler: EventHandler): void;
58
- removeHandler(eventType: ProviderEvents, handler: EventHandler): void;
111
+ emit<T extends ProviderEvents>(eventType: T, context?: EventContext<T, AdditionalContext>): void;
112
+ addHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
113
+ removeHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
59
114
  removeAllHandlers(eventType?: ProviderEvents): void;
60
- getHandlers(eventType: ProviderEvents): EventHandler[];
115
+ getHandlers<T extends ProviderEvents>(eventType: T): EventHandler<T>[];
61
116
  setLogger(logger: Logger): this;
62
117
  private get _logger();
63
118
  }
119
+ /**
120
+ * The OpenFeatureEventEmitter can be used by provider developers to emit
121
+ * events at various parts of the provider lifecycle.
122
+ *
123
+ * NOTE: Ready and error events are automatically emitted by the SDK based on
124
+ * the result of the initialize method.
125
+ */
126
+ declare class OpenFeatureEventEmitter extends GenericEventEmitter {
127
+ }
128
+ /**
129
+ * The InternalEventEmitter should only be used within the SDK. It extends the
130
+ * OpenFeatureEventEmitter to include additional properties that can be included
131
+ * in the event details.
132
+ */
133
+ declare class InternalEventEmitter extends GenericEventEmitter<CommonEventDetails> {
134
+ }
135
+
136
+ interface Metadata {
137
+ }
64
138
 
139
+ type FlagValueType = 'boolean' | 'string' | 'number' | 'object';
65
140
  type PrimitiveValue = null | boolean | string | number;
66
141
  type JsonObject = {
67
142
  [key: string]: JsonValue;
@@ -74,28 +149,26 @@ type JsonValue = PrimitiveValue | JsonObject | JsonArray;
74
149
  /**
75
150
  * Represents a JSON node value, or Date.
76
151
  */
77
- type EvaluationContextValue = PrimitiveValue | Date | {
78
- [key: string]: EvaluationContextValue;
79
- } | EvaluationContextValue[];
152
+ type FlagValue = boolean | string | number | JsonValue;
153
+ type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>);
80
154
  /**
81
- * A container for arbitrary contextual data that can be used as a basis for dynamic evaluation
155
+ * A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
156
+ *
157
+ * This structure is populated by a provider for use by an Application Author (via the Evaluation API) or an Application Integrator (via hooks).
82
158
  */
83
- type EvaluationContext = {
84
- /**
85
- * A string uniquely identifying the subject (end-user, or client service) of a flag evaluation.
86
- * Providers may require this field for fractional flag evaluation, rules, or overrides targeting specific users.
87
- * Such providers may behave unpredictably if a targeting key is not specified at flag resolution.
88
- */
89
- targetingKey?: string;
90
- } & Record<string, EvaluationContextValue>;
91
- type FlagValue = boolean | string | number | JsonValue;
92
- type FlagValueType = 'boolean' | 'string' | 'number' | 'object';
93
- interface Logger {
94
- error(...args: unknown[]): void;
95
- warn(...args: unknown[]): void;
96
- info(...args: unknown[]): void;
97
- debug(...args: unknown[]): void;
98
- }
159
+ type FlagMetadata = Record<string, string | number | boolean>;
160
+ type ResolutionDetails<U> = {
161
+ value: U;
162
+ variant?: string;
163
+ flagMetadata?: FlagMetadata;
164
+ reason?: ResolutionReason;
165
+ errorCode?: ErrorCode;
166
+ errorMessage?: string;
167
+ };
168
+ type EvaluationDetails<T extends FlagValue> = {
169
+ flagKey: string;
170
+ flagMetadata: Readonly<FlagMetadata>;
171
+ } & ResolutionDetails<T>;
99
172
  declare const StandardResolutionReasons: {
100
173
  /**
101
174
  * The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.
@@ -162,25 +235,21 @@ declare enum ErrorCode {
162
235
  */
163
236
  GENERAL = "GENERAL"
164
237
  }
165
- type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>);
238
+
239
+ type EvaluationContextValue = PrimitiveValue | Date | {
240
+ [key: string]: EvaluationContextValue;
241
+ } | EvaluationContextValue[];
166
242
  /**
167
- * A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number.
168
- *
169
- * This structure is populated by a provider for use by an Application Author (via the Evaluation API) or an Application Integrator (via hooks).
243
+ * A container for arbitrary contextual data that can be used as a basis for dynamic evaluation
170
244
  */
171
- type FlagMetadata = Record<string, string | number | boolean>;
172
- type ResolutionDetails<U> = {
173
- value: U;
174
- variant?: string;
175
- flagMetadata?: FlagMetadata;
176
- reason?: ResolutionReason;
177
- errorCode?: ErrorCode;
178
- errorMessage?: string;
179
- };
180
- type EvaluationDetails<T extends FlagValue> = {
181
- flagKey: string;
182
- flagMetadata: Readonly<FlagMetadata>;
183
- } & ResolutionDetails<T>;
245
+ type EvaluationContext = {
246
+ /**
247
+ * A string uniquely identifying the subject (end-user, or client service) of a flag evaluation.
248
+ * Providers may require this field for fractional flag evaluation, rules, or overrides targeting specific users.
249
+ * Such providers may behave unpredictably if a targeting key is not specified at flag resolution.
250
+ */
251
+ targetingKey?: string;
252
+ } & Record<string, EvaluationContextValue>;
184
253
  interface ManageContext<T> {
185
254
  /**
186
255
  * Access the evaluation context set on the receiver.
@@ -196,29 +265,42 @@ interface ManageContext<T> {
196
265
  */
197
266
  setContext(context: EvaluationContext): T;
198
267
  }
199
- interface ManageLogger<T> {
268
+
269
+ declare enum ProviderStatus {
270
+ NOT_READY = "NOT_READY",
271
+ READY = "READY",
272
+ ERROR = "ERROR"
273
+ }
274
+ interface ProviderMetadata extends Metadata {
275
+ readonly name: string;
276
+ }
277
+ interface CommonProvider {
278
+ readonly metadata: ProviderMetadata;
279
+ readonly status?: ProviderStatus;
200
280
  /**
201
- * Sets a logger on this receiver. This logger supersedes to the global logger
202
- * and is passed to various components in the SDK.
203
- * The logger configured on the global API object will be used for all evaluations,
204
- * unless overridden in a particular client.
205
- * @template T The type of the receiver
206
- * @param {Logger} logger The logger to be used
207
- * @returns {T} The receiver (this object)
281
+ * An event emitter for ProviderEvents.
282
+ * @see ProviderEvents
208
283
  */
209
- setLogger(logger: Logger): T;
210
- }
211
- type HookHints = Readonly<Record<string, unknown>>;
212
- interface Metadata {
284
+ events?: OpenFeatureEventEmitter;
285
+ onClose?(): Promise<void>;
286
+ /**
287
+ * A handler function used to setup the provider.
288
+ * Called by the SDK after the provider is set.
289
+ * When the returned promise resolves, the SDK fires the ProviderEvents.Ready event.
290
+ * If the returned promise rejects, the SDK fires the ProviderEvents.Error event.
291
+ * Use this function to perform any context-dependent setup within the provider.
292
+ * @param context
293
+ */
294
+ initialize?(context?: EvaluationContext): Promise<void>;
213
295
  }
296
+
214
297
  interface ClientMetadata extends Metadata {
215
298
  readonly version?: string;
216
299
  readonly name?: string;
217
300
  readonly providerMetadata: ProviderMetadata;
218
301
  }
219
- interface ProviderMetadata extends Metadata {
220
- readonly name: string;
221
- }
302
+
303
+ type HookHints = Readonly<Record<string, unknown>>;
222
304
  interface HookContext<T extends FlagValue = FlagValue> {
223
305
  readonly flagKey: string;
224
306
  readonly defaultValue: T;
@@ -231,74 +313,61 @@ interface HookContext<T extends FlagValue = FlagValue> {
231
313
  interface BeforeHookContext extends HookContext {
232
314
  context: EvaluationContext;
233
315
  }
234
- /**
235
- * Transaction context is a mechanism for adding transaction specific context that
236
- * is merged with evaluation context prior to flag evaluation. Examples of potential
237
- * transaction specific context include: a user id, user agent, or request path.
238
- */
239
- type TransactionContext = EvaluationContext;
240
- interface ManageTransactionContextPropagator<T> extends TransactionContextPropagator {
316
+
317
+ interface Hook<T extends FlagValue = FlagValue> {
241
318
  /**
242
- * EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
243
- * The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
244
- *
245
- * Sets a transaction context propagator on this receiver. The transaction context
246
- * propagator is responsible for persisting context for the duration of a single
247
- * transaction.
248
- * @experimental
249
- * @template T The type of the receiver
250
- * @param {TransactionContextPropagator} transactionContextPropagator The context propagator to be used
251
- * @returns {T} The receiver (this object)
319
+ * Runs before flag values are resolved from the provider.
320
+ * If an EvaluationContext is returned, it will be merged with the pre-existing EvaluationContext.
321
+ * @param hookContext
322
+ * @param hookHints
252
323
  */
253
- setTransactionContextPropagator(transactionContextPropagator: TransactionContextPropagator): T;
254
- }
255
- interface TransactionContextPropagator {
324
+ before?(hookContext: BeforeHookContext, hookHints?: HookHints): Promise<EvaluationContext | void> | EvaluationContext | void;
256
325
  /**
257
- * EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
258
- * The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
259
- *
260
- * Returns the currently defined transaction context using the registered transaction
261
- * context propagator.
262
- * @experimental
263
- * @returns {TransactionContext} The current transaction context
326
+ * Runs after flag values are successfully resolved from the provider.
327
+ * @param hookContext
328
+ * @param evaluationDetails
329
+ * @param hookHints
264
330
  */
265
- getTransactionContext(): TransactionContext;
331
+ after?(hookContext: Readonly<HookContext<T>>, evaluationDetails: EvaluationDetails<T>, hookHints?: HookHints): Promise<void> | void;
266
332
  /**
267
- * EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
268
- * The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
269
- *
270
- * Sets the transaction context using the registered transaction context propagator.
271
- * @experimental
272
- * @template R The return value of the callback
273
- * @param {TransactionContext} transactionContext The transaction specific context
274
- * @param {(...args: unknown[]) => R} callback Callback function used to set the transaction context on the stack
275
- * @param {...unknown[]} args Optional arguments that are passed to the callback function
333
+ * Runs in the event of an unhandled error or promise rejection during flag resolution, or any attached hooks.
334
+ * @param hookContext
335
+ * @param error
336
+ * @param hookHints
276
337
  */
277
- setTransactionContext<R>(transactionContext: TransactionContext, callback: (...args: unknown[]) => R, ...args: unknown[]): void;
278
- }
279
- declare enum ProviderStatus {
280
- NOT_READY = "NOT_READY",
281
- READY = "READY",
282
- ERROR = "ERROR"
338
+ error?(hookContext: Readonly<HookContext<T>>, error: unknown, hookHints?: HookHints): Promise<void> | void;
339
+ /**
340
+ * Runs after all other hook stages, regardless of success or error.
341
+ * Errors thrown here are unhandled by the client and will surface in application code.
342
+ * @param hookContext
343
+ * @param hookHints
344
+ */
345
+ finally?(hookContext: Readonly<HookContext<T>>, hookHints?: HookHints): Promise<void> | void;
283
346
  }
284
- interface CommonProvider {
285
- readonly metadata: ProviderMetadata;
286
- readonly status?: ProviderStatus;
347
+
348
+ interface EvaluationLifeCycle<T> {
349
+ /**
350
+ * Adds hooks that will run during flag evaluations on this receiver.
351
+ * Hooks are executed in the order they were registered. Adding additional hooks
352
+ * will not remove existing hooks.
353
+ * Hooks registered on the global API object run with all evaluations.
354
+ * Hooks registered on the client run with all evaluations on that client.
355
+ * @template T The type of the receiver
356
+ * @param {Hook<FlagValue>[]} hooks A list of hooks that should always run
357
+ * @returns {T} The receiver (this object)
358
+ */
359
+ addHooks(...hooks: Hook<FlagValue>[]): T;
287
360
  /**
288
- * An event emitter for ProviderEvents.
289
- * @see ProviderEvents
361
+ * Access all the hooks that are registered on this receiver.
362
+ * @returns {Hook<FlagValue>[]} A list of the client hooks
290
363
  */
291
- events?: OpenFeatureEventEmitter;
292
- onClose?(): Promise<void>;
364
+ getHooks(): Hook<FlagValue>[];
293
365
  /**
294
- * A handler function used to setup the provider.
295
- * Called by the SDK after the provider is set.
296
- * When the returned promise resolves, the SDK fires the ProviderEvents.Ready event.
297
- * If the returned promise rejects, the SDK fires the ProviderEvents.Error event.
298
- * Use this function to perform any context-dependent setup within the provider.
299
- * @param context
366
+ * Clears all the hooks that are registered on this receiver.
367
+ * @template T The type of the receiver
368
+ * @returns {T} The receiver (this object)
300
369
  */
301
- initialize?(context?: EvaluationContext): Promise<void>;
370
+ clearHooks(): T;
302
371
  }
303
372
 
304
373
  declare abstract class OpenFeatureError extends Error {
@@ -336,21 +405,50 @@ declare class InvalidContextError extends OpenFeatureError {
336
405
  constructor(message?: string);
337
406
  }
338
407
 
339
- declare class DefaultLogger implements Logger {
340
- error(...args: unknown[]): void;
341
- warn(...args: unknown[]): void;
342
- info(): void;
343
- debug(): void;
408
+ /**
409
+ * Transaction context is a mechanism for adding transaction specific context that
410
+ * is merged with evaluation context prior to flag evaluation. Examples of potential
411
+ * transaction specific context include: a user id, user agent, or request path.
412
+ */
413
+ type TransactionContext = EvaluationContext;
414
+ interface ManageTransactionContextPropagator<T> extends TransactionContextPropagator {
415
+ /**
416
+ * EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
417
+ * The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
418
+ *
419
+ * Sets a transaction context propagator on this receiver. The transaction context
420
+ * propagator is responsible for persisting context for the duration of a single
421
+ * transaction.
422
+ * @experimental
423
+ * @template T The type of the receiver
424
+ * @param {TransactionContextPropagator} transactionContextPropagator The context propagator to be used
425
+ * @returns {T} The receiver (this object)
426
+ */
427
+ setTransactionContextPropagator(transactionContextPropagator: TransactionContextPropagator): T;
344
428
  }
345
- declare class SafeLogger implements Logger {
346
- private readonly logger;
347
- private readonly fallbackLogger;
348
- constructor(logger: Logger);
349
- error(...args: unknown[]): void;
350
- warn(...args: unknown[]): void;
351
- info(...args: unknown[]): void;
352
- debug(...args: unknown[]): void;
353
- private log;
429
+ interface TransactionContextPropagator {
430
+ /**
431
+ * EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
432
+ * The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
433
+ *
434
+ * Returns the currently defined transaction context using the registered transaction
435
+ * context propagator.
436
+ * @experimental
437
+ * @returns {TransactionContext} The current transaction context
438
+ */
439
+ getTransactionContext(): TransactionContext;
440
+ /**
441
+ * EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
442
+ * The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
443
+ *
444
+ * Sets the transaction context using the registered transaction context propagator.
445
+ * @experimental
446
+ * @template R The return value of the callback
447
+ * @param {TransactionContext} transactionContext The transaction specific context
448
+ * @param {(...args: unknown[]) => R} callback Callback function used to set the transaction context on the stack
449
+ * @param {...unknown[]} args Optional arguments that are passed to the callback function
450
+ */
451
+ setTransactionContext<R>(transactionContext: TransactionContext, callback: (...args: unknown[]) => R, ...args: unknown[]): void;
354
452
  }
355
453
 
356
454
  declare class NoopTransactionContextPropagator implements TransactionContextPropagator {
@@ -359,7 +457,33 @@ declare class NoopTransactionContextPropagator implements TransactionContextProp
359
457
  }
360
458
  declare const NOOP_TRANSACTION_CONTEXT_PROPAGATOR: NoopTransactionContextPropagator;
361
459
 
362
- declare abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonProvider> implements Eventing {
460
+ /**
461
+ * Checks whether the parameter is a string.
462
+ * @param {unknown} value The value to check
463
+ * @returns {value is string} True if the value is a string
464
+ */
465
+ declare function isString(value: unknown): value is string;
466
+ /**
467
+ * Returns the parameter if it is a string, otherwise returns undefined.
468
+ * @param {unknown} value The value to check
469
+ * @returns {string|undefined} The parameter if it is a string, otherwise undefined
470
+ */
471
+ declare function stringOrUndefined(value: unknown): string | undefined;
472
+ /**
473
+ * Checks whether the parameter is an object.
474
+ * @param {unknown} value The value to check
475
+ * @returns {value is string} True if the value is an object
476
+ */
477
+ declare function isObject<T extends object>(value: unknown): value is T;
478
+ /**
479
+ * Returns the parameter if it is an object, otherwise returns undefined.
480
+ * @param {unknown} value The value to check
481
+ * @returns {object|undefined} The parameter if it is an object, otherwise undefined
482
+ */
483
+ declare function objectOrUndefined<T extends object>(value: unknown): T | undefined;
484
+
485
+ declare abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonProvider> implements Eventing, EvaluationLifeCycle<OpenFeatureCommonAPI<P>>, ManageLogger<OpenFeatureCommonAPI<P>>, ManageTransactionContextPropagator<OpenFeatureCommonAPI<P>> {
486
+ protected _hooks: Hook[];
363
487
  protected _transactionContextPropagator: TransactionContextPropagator;
364
488
  protected _context: EvaluationContext;
365
489
  protected _logger: Logger;
@@ -367,15 +491,16 @@ declare abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonPro
367
491
  private readonly _events;
368
492
  private readonly _clientEventHandlers;
369
493
  protected _clientProviders: Map<string, P>;
370
- protected _clientEvents: Map<string | undefined, OpenFeatureEventEmitter>;
371
- abstract clearHooks(): this;
494
+ protected _clientEvents: Map<string | undefined, InternalEventEmitter>;
495
+ addHooks(...hooks: Hook<FlagValue>[]): this;
496
+ getHooks(): Hook<FlagValue>[];
497
+ clearHooks(): this;
372
498
  setLogger(logger: Logger): this;
373
499
  /**
374
500
  * Get metadata about registered provider.
375
501
  * @returns {ProviderMetadata} Provider Metadata
376
502
  */
377
503
  get providerMetadata(): ProviderMetadata;
378
- getContext(): EvaluationContext;
379
504
  /**
380
505
  * Adds a handler for the given provider event type.
381
506
  * The handlers are called in the order they have been added.
@@ -383,19 +508,19 @@ declare abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonPro
383
508
  * @param {ProviderEvents} eventType The provider event type to listen to
384
509
  * @param {EventHandler} handler The handler to run on occurrence of the event type
385
510
  */
386
- addHandler(eventType: ProviderEvents, handler: EventHandler): void;
511
+ addHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
387
512
  /**
388
513
  * Removes a handler for the given provider event type.
389
514
  * @param {ProviderEvents} eventType The provider event type to remove the listener for
390
515
  * @param {EventHandler} handler The handler to remove for the provider event type
391
516
  */
392
- removeHandler(eventType: ProviderEvents, handler: EventHandler): void;
517
+ removeHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
393
518
  /**
394
519
  * Gets the current handlers for the given provider event type.
395
520
  * @param {ProviderEvents} eventType The provider event type to get the current handlers for
396
521
  * @returns {EventHandler[]} The handlers currently attached to the given provider event type
397
522
  */
398
- getHandlers(eventType: ProviderEvents): EventHandler[];
523
+ getHandlers<T extends ProviderEvents>(eventType: T): EventHandler<T>[];
399
524
  /**
400
525
  * Sets the default provider for flag evaluations.
401
526
  * This provider will be used by unnamed clients and named clients to which no provider is bound.
@@ -415,8 +540,9 @@ declare abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonPro
415
540
  */
416
541
  setProvider(clientName: string, provider: P): this;
417
542
  protected getProviderForClient(name?: string): P;
418
- protected getAndCacheEventEmitterForClient(name?: string): OpenFeatureEventEmitter;
543
+ protected buildAndCacheEventEmitterForClient(name?: string): InternalEventEmitter;
419
544
  private getUnboundEmitters;
545
+ private getAssociatedEventEmitters;
420
546
  private transferListeners;
421
547
  close(): Promise<void>;
422
548
  private handleShutdownError;
@@ -425,98 +551,6 @@ declare abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonPro
425
551
  getTransactionContext(): TransactionContext;
426
552
  }
427
553
 
428
- /**
429
- * Interface that providers must implement to resolve flag values for their particular
430
- * backend or vendor.
431
- *
432
- * Implementation for resolving all the required flag types must be defined.
433
- */
434
- interface Provider extends CommonProvider {
435
- /**
436
- * A provider hook exposes a mechanism for provider authors to register hooks
437
- * to tap into various stages of the flag evaluation lifecycle. These hooks can
438
- * be used to perform side effects and mutate the context for purposes of the
439
- * provider. Provider hooks are not configured or controlled by the application author.
440
- */
441
- readonly hooks?: Hook[];
442
- /**
443
- * A handler function to reconcile changes when the static context.
444
- * Called by the SDK when the context is changed.
445
- * @param oldContext
446
- * @param newContext
447
- */
448
- onContextChange?(oldContext: EvaluationContext, newContext: EvaluationContext): Promise<void>;
449
- /**
450
- * Resolve a boolean flag and its evaluation details.
451
- */
452
- resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext, logger: Logger): ResolutionDetails<boolean>;
453
- /**
454
- * Resolve a string flag and its evaluation details.
455
- */
456
- resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext, logger: Logger): ResolutionDetails<string>;
457
- /**
458
- * Resolve a numeric flag and its evaluation details.
459
- */
460
- resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext, logger: Logger): ResolutionDetails<number>;
461
- /**
462
- * Resolve and parse an object flag and its evaluation details.
463
- */
464
- resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext, logger: Logger): ResolutionDetails<T>;
465
- }
466
- interface Hook<T extends FlagValue = FlagValue> {
467
- /**
468
- * Runs before flag values are resolved from the provider.
469
- * If an EvaluationContext is returned, it will be merged with the pre-existing EvaluationContext.
470
- * @param hookContext
471
- * @param hookHints
472
- */
473
- before?(hookContext: BeforeHookContext, hookHints?: HookHints): EvaluationContext | void;
474
- /**
475
- * Runs after flag values are successfully resolved from the provider.
476
- * @param hookContext
477
- * @param evaluationDetails
478
- * @param hookHints
479
- */
480
- after?(hookContext: Readonly<HookContext<T>>, evaluationDetails: EvaluationDetails<T>, hookHints?: HookHints): void;
481
- /**
482
- * Runs in the event of an unhandled error or promise rejection during flag resolution, or any attached hooks.
483
- * @param hookContext
484
- * @param error
485
- * @param hookHints
486
- */
487
- error?(hookContext: Readonly<HookContext<T>>, error: unknown, hookHints?: HookHints): void;
488
- /**
489
- * Runs after all other hook stages, regardless of success or error.
490
- * Errors thrown here are unhandled by the client and will surface in application code.
491
- * @param hookContext
492
- * @param hookHints
493
- */
494
- finally?(hookContext: Readonly<HookContext<T>>, hookHints?: HookHints): void;
495
- }
496
- interface EvaluationLifeCycle<T> {
497
- /**
498
- * Adds hooks that will run during flag evaluations on this receiver.
499
- * Hooks are executed in the order they were registered. Adding additional hooks
500
- * will not remove existing hooks.
501
- * Hooks registered on the global API object run with all evaluations.
502
- * Hooks registered on the client run with all evaluations on that client.
503
- * @template T The type of the receiver
504
- * @param {Hook<FlagValue>[]} hooks A list of hooks that should always run
505
- * @returns {T} The receiver (this object)
506
- */
507
- addHooks(...hooks: Hook[]): T;
508
- /**
509
- * Access all the hooks that are registered on this receiver.
510
- * @returns {Hook<FlagValue>[]} A list of the client hooks
511
- */
512
- getHooks(): Hook[];
513
- /**
514
- * Clears all the hooks that are registered on this receiver.
515
- * @template T The type of the receiver
516
- * @returns {T} The receiver (this object)
517
- */
518
- clearHooks(): T;
519
- }
520
554
  interface FlagEvaluationOptions {
521
555
  hooks?: Hook[];
522
556
  hookHints?: HookHints;
@@ -599,29 +633,65 @@ interface Features {
599
633
  getObjectDetails(flagKey: string, defaultValue: JsonValue, options?: FlagEvaluationOptions): EvaluationDetails<JsonValue>;
600
634
  getObjectDetails<T extends JsonValue = JsonValue>(flagKey: string, defaultValue: T, options?: FlagEvaluationOptions): EvaluationDetails<T>;
601
635
  }
636
+
602
637
  interface Client extends EvaluationLifeCycle<Client>, Features, ManageLogger<Client>, Eventing {
603
638
  readonly metadata: ClientMetadata;
604
639
  }
605
- interface GlobalApi extends EvaluationLifeCycle<GlobalApi>, ManageContext<GlobalApi>, ManageLogger<GlobalApi>, ManageTransactionContextPropagator<GlobalApi> {
606
- readonly providerMetadata: ProviderMetadata;
640
+
641
+ /**
642
+ * Interface that providers must implement to resolve flag values for their particular
643
+ * backend or vendor.
644
+ *
645
+ * Implementation for resolving all the required flag types must be defined.
646
+ */
647
+ interface Provider extends CommonProvider {
607
648
  /**
608
- * A factory function for creating new OpenFeature clients. Clients can contain
609
- * their own state (e.g. logger, hook, context). Multiple clients can be used
610
- * to segment feature flag configuration.
611
- * @param {string} name The name of the client
612
- * @param {string} version The version of the client
613
- * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations
614
- * @returns {Client} OpenFeature Client
649
+ * A provider hook exposes a mechanism for provider authors to register hooks
650
+ * to tap into various stages of the flag evaluation lifecycle. These hooks can
651
+ * be used to perform side effects and mutate the context for purposes of the
652
+ * provider. Provider hooks are not configured or controlled by the application author.
653
+ */
654
+ readonly hooks?: Hook[];
655
+ /**
656
+ * A handler function to reconcile changes when the static context.
657
+ * Called by the SDK when the context is changed.
658
+ * @param oldContext
659
+ * @param newContext
660
+ */
661
+ onContextChange?(oldContext: EvaluationContext, newContext: EvaluationContext): Promise<void>;
662
+ /**
663
+ * Resolve a boolean flag and its evaluation details.
664
+ */
665
+ resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext, logger: Logger): ResolutionDetails<boolean>;
666
+ /**
667
+ * Resolve a string flag and its evaluation details.
615
668
  */
616
- getClient(name?: string, version?: string, context?: EvaluationContext): Client;
669
+ resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext, logger: Logger): ResolutionDetails<string>;
670
+ /**
671
+ * Resolve a numeric flag and its evaluation details.
672
+ */
673
+ resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext, logger: Logger): ResolutionDetails<number>;
617
674
  /**
618
- * Sets the provider that OpenFeature will use for flag evaluations. Setting
619
- * a provider supersedes the current provider used in new and existing clients.
620
- * @param {Provider} provider The provider responsible for flag evaluations.
621
- * @returns {GlobalApi} OpenFeature API
675
+ * Resolve and parse an object flag and its evaluation details.
622
676
  */
623
- setProvider(provider: Provider): GlobalApi;
677
+ resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext, logger: Logger): ResolutionDetails<T>;
678
+ }
679
+
680
+ /**
681
+ * The No-op provider is set by default, and simply always returns the default value.
682
+ */
683
+ declare class NoopFeatureProvider implements Provider {
684
+ readonly metadata: {
685
+ readonly name: "No-op Provider";
686
+ };
687
+ get status(): ProviderStatus;
688
+ resolveBooleanEvaluation(_: string, defaultValue: boolean): ResolutionDetails<boolean>;
689
+ resolveStringEvaluation(_: string, defaultValue: string): ResolutionDetails<string>;
690
+ resolveNumberEvaluation(_: string, defaultValue: number): ResolutionDetails<number>;
691
+ resolveObjectEvaluation<T extends JsonValue>(_: string, defaultValue: T): ResolutionDetails<T>;
692
+ private noOp;
624
693
  }
694
+ declare const NOOP_PROVIDER: NoopFeatureProvider;
625
695
 
626
696
  type OpenFeatureClientOptions = {
627
697
  name?: string;
@@ -636,13 +706,13 @@ declare class OpenFeatureClient implements Client {
636
706
  private _clientLogger?;
637
707
  constructor(providerAccessor: () => Provider, emitterAccessor: () => OpenFeatureEventEmitter, globalLogger: () => Logger, options: OpenFeatureClientOptions);
638
708
  get metadata(): ClientMetadata;
639
- addHandler(eventType: ProviderEvents, handler: EventHandler): void;
640
- removeHandler(notificationType: ProviderEvents, handler: EventHandler): void;
641
- getHandlers(eventType: ProviderEvents): EventHandler[];
642
- setLogger(logger: Logger): OpenFeatureClient;
643
- addHooks(...hooks: Hook<FlagValue>[]): OpenFeatureClient;
709
+ addHandler<T extends ProviderEvents>(eventType: T, handler: EventHandler<T>): void;
710
+ removeHandler<T extends ProviderEvents>(notificationType: T, handler: EventHandler<T>): void;
711
+ getHandlers(eventType: ProviderEvents): EventHandler<ProviderEvents>[];
712
+ setLogger(logger: Logger): this;
713
+ addHooks(...hooks: Hook<FlagValue>[]): this;
644
714
  getHooks(): Hook<FlagValue>[];
645
- clearHooks(): OpenFeatureClient;
715
+ clearHooks(): this;
646
716
  getBooleanValue(flagKey: string, defaultValue: boolean, options?: FlagEvaluationOptions): boolean;
647
717
  getBooleanDetails(flagKey: string, defaultValue: boolean, options?: FlagEvaluationOptions): EvaluationDetails<boolean>;
648
718
  getStringValue<T extends string = string>(flagKey: string, defaultValue: T, options?: FlagEvaluationOptions): T;
@@ -660,24 +730,7 @@ declare class OpenFeatureClient implements Client {
660
730
  private get _logger();
661
731
  }
662
732
 
663
- /**
664
- * The No-op provider is set by default, and simply always returns the default value.
665
- */
666
- declare class NoopFeatureProvider implements Provider {
667
- readonly metadata: {
668
- readonly name: "No-op Provider";
669
- };
670
- get status(): ProviderStatus;
671
- resolveBooleanEvaluation(_: string, defaultValue: boolean): ResolutionDetails<boolean>;
672
- resolveStringEvaluation(_: string, defaultValue: string): ResolutionDetails<string>;
673
- resolveNumberEvaluation(_: string, defaultValue: number): ResolutionDetails<number>;
674
- resolveObjectEvaluation<T extends JsonValue>(_: string, defaultValue: T): ResolutionDetails<T>;
675
- private noOp;
676
- }
677
- declare const NOOP_PROVIDER: NoopFeatureProvider;
678
-
679
- declare class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider> {
680
- protected _hooks: Hook[];
733
+ declare class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider> implements ManageContext<Promise<void>> {
681
734
  protected _defaultProvider: Provider;
682
735
  private constructor();
683
736
  /**
@@ -686,11 +739,8 @@ declare class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider> {
686
739
  * @returns {OpenFeatureAPI} OpenFeature API
687
740
  */
688
741
  static getInstance(): OpenFeatureAPI;
689
- setLogger(logger: Logger): this;
690
- addHooks(...hooks: Hook<FlagValue>[]): this;
691
- getHooks(): Hook<FlagValue>[];
692
- clearHooks(): this;
693
742
  setContext(context: EvaluationContext): Promise<void>;
743
+ getContext(): EvaluationContext;
694
744
  /**
695
745
  * A factory function for creating new named OpenFeature clients. Clients can contain
696
746
  * their own state (e.g. logger, hook, context). Multiple clients can be used
@@ -710,4 +760,4 @@ declare class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider> {
710
760
  */
711
761
  declare const OpenFeature: OpenFeatureAPI;
712
762
 
713
- export { BeforeHookContext, Client, ClientMetadata, CommonProvider, DefaultLogger, ErrorCode, EvaluationContext, EvaluationContextValue, EvaluationDetails, EventDetails, EventHandler, EventMetadata, Eventing, Features, FlagEvaluationOptions, FlagMetadata, FlagNotFoundError, FlagValue, FlagValueType, GeneralError, GlobalApi, Hook, HookContext, HookHints, InvalidContextError, JsonArray, JsonObject, JsonValue, Logger, ManageContext, ManageLogger, ManageTransactionContextPropagator, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureCommonAPI, OpenFeatureError, OpenFeatureEventEmitter, ParseError, PrimitiveValue, Provider, ProviderEvents, ProviderMetadata, ProviderStatus, ResolutionDetails, ResolutionReason, SafeLogger, StandardResolutionReasons, TargetingKeyMissingError, TransactionContext, TransactionContextPropagator, TypeMismatchError };
763
+ export { BeforeHookContext, Client, ClientMetadata, CommonEventDetails, CommonProvider, ConfigChangeEvent, DefaultLogger, ErrorCode, ErrorEvent, EvaluationContext, EvaluationContextValue, EvaluationDetails, EvaluationLifeCycle, EventContext, EventDetails, EventHandler, EventMetadata, Eventing, Features, FlagEvaluationOptions, FlagMetadata, FlagNotFoundError, FlagValue, FlagValueType, GeneralError, Hook, HookContext, HookHints, InternalEventEmitter, InvalidContextError, JsonArray, JsonObject, JsonValue, LOG_LEVELS, Logger, ManageContext, ManageLogger, ManageTransactionContextPropagator, Metadata, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureCommonAPI, OpenFeatureError, OpenFeatureEventEmitter, ParseError, PrimitiveValue, Provider, ProviderEvents, ProviderMetadata, ProviderStatus, ReadyEvent, ResolutionDetails, ResolutionReason, SafeLogger, StaleEvent, StandardResolutionReasons, TargetingKeyMissingError, TransactionContext, TransactionContextPropagator, TypeMismatchError, isObject, isString, objectOrUndefined, stringOrUndefined };