@openfeature/server-sdk 1.10.0 → 1.12.0

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/README.md CHANGED
@@ -16,8 +16,8 @@
16
16
  <img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.7.0&color=yellow&style=for-the-badge" />
17
17
  </a>
18
18
  <!-- x-release-please-start-version -->
19
- <a href="https://github.com/open-feature/js-sdk/releases/tag/server-sdk-v1.10.0">
20
- <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.10.0&color=blue&style=for-the-badge" />
19
+ <a href="https://github.com/open-feature/js-sdk/releases/tag/server-sdk-v1.12.0">
20
+ <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.12.0&color=blue&style=for-the-badge" />
21
21
  </a>
22
22
  <!-- x-release-please-end -->
23
23
  <br/>
@@ -86,16 +86,16 @@ See [here](https://open-feature.github.io/js-sdk/modules/_openfeature_server_sdk
86
86
 
87
87
  ## 🌟 Features
88
88
 
89
- | Status | Features | Description |
90
- | ------ | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
91
- | ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
92
- | ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
93
- | ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
94
- | ✅ | [Logging](#logging) | Integrate with popular logging packages. |
95
- | ✅ | [Named clients](#named-clients) | Utilize multiple providers in a single application. |
96
- | ✅ | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
97
- | ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
98
- | ✅ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |
89
+ | Status | Features | Description |
90
+ | ------ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
91
+ | ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
92
+ | ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
93
+ | ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
94
+ | ✅ | [Logging](#logging) | Integrate with popular logging packages. |
95
+ | ✅ | [Domains](#domains) | Logically bind clients with providers. |
96
+ | ✅ | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
97
+ | ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
98
+ | ✅ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |
99
99
 
100
100
  <sub>Implemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌</sub>
101
101
 
@@ -126,7 +126,7 @@ OpenFeature.setProvider(new MyProvider());
126
126
  Once the provider has been registered, the status can be tracked using [events](#eventing).
127
127
 
128
128
  In some situations, it may be beneficial to register multiple providers in the same application.
129
- This is possible using [named clients](#named-clients), which is covered in more details below.
129
+ This is possible using [domains](#domains), which is covered in more details below.
130
130
 
131
131
  ### Targeting
132
132
 
@@ -154,7 +154,7 @@ const boolValue = await client.getBooleanValue('some-flag', false, requestContex
154
154
 
155
155
  ### Hooks
156
156
 
157
- [Hooks](https://openfeature.dev/docs/reference/concepts/hooks) allow for custom logic to be added at well-defined points of the flag evaluation life-cycle
157
+ [Hooks](https://openfeature.dev/docs/reference/concepts/hooks) allow for custom logic to be added at well-defined points of the flag evaluation life-cycle.
158
158
  Look [here](https://openfeature.dev/ecosystem/?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Hook&instant_search%5BrefinementList%5D%5Bcategory%5D%5B0%5D=Server-side&instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=JavaScript) for a complete list of available hooks.
159
159
  If the hook you're looking for hasn't been created yet, see the [develop a hook](#develop-a-hook) section to learn how to build it yourself.
160
160
 
@@ -176,7 +176,7 @@ const boolValue = await client.getBooleanValue("bool-flag", false, { hooks: [new
176
176
 
177
177
  ### Logging
178
178
 
179
- The JS SDK will log warning and errors to the console by default.
179
+ The Node.JS SDK will log warnings and errors to the console by default.
180
180
  This behavior can be overridden by passing a custom logger either globally or per client.
181
181
  A custom logger must implement the [Logger interface](../shared/src/logger/logger.ts).
182
182
 
@@ -194,11 +194,11 @@ const client = OpenFeature.getClient();
194
194
  client.setLogger(logger);
195
195
  ```
196
196
 
197
- ### Named clients
197
+ ### Domains
198
198
 
199
- Clients can be given a name.
200
- A name is a logical identifier which can be used to associate clients with a particular provider.
201
- If a name has no associated provider, the global provider is used.
199
+ Clients can be assigned to a domain.
200
+ A domain is a logical identifier which can be used to associate clients with a particular provider.
201
+ If a domain has no associated provider, the default provider is used.
202
202
 
203
203
  ```ts
204
204
  import { OpenFeature, InMemoryProvider } from "@openfeature/server-sdk";
@@ -216,16 +216,16 @@ const myFlags = {
216
216
 
217
217
  // Registering the default provider
218
218
  OpenFeature.setProvider(InMemoryProvider(myFlags));
219
- // Registering a named provider
220
- OpenFeature.setProvider("otherClient", new InMemoryProvider(someOtherFlags));
219
+ // Registering a provider to a domain
220
+ OpenFeature.setProvider("my-domain", new InMemoryProvider(someOtherFlags));
221
221
 
222
- // A Client backed by default provider
222
+ // A Client bound to the default provider
223
223
  const clientWithDefault = OpenFeature.getClient();
224
- // A Client backed by NewCachedProvider
225
- const clientForCache = OpenFeature.getClient("otherClient");
224
+ // A Client bound to the InMemoryProvider provider
225
+ const domainScopedClient = OpenFeature.getClient("my-domain");
226
226
  ```
227
227
 
228
- Named providers can be set in an awaitable or synchronous way.
228
+ Domains can be defined on a provider during registration.
229
229
  For more details, please refer to the [providers](#providers) section.
230
230
 
231
231
  ### Eventing
@@ -271,43 +271,48 @@ This can be a new repository or included in [the existing contrib repository](ht
271
271
  You’ll then need to write the provider by implementing the [Provider interface](./src/provider/provider.ts) exported by the OpenFeature SDK.
272
272
 
273
273
  ```ts
274
- import { JsonValue, Provider, ResolutionDetails } from '@openfeature/server-sdk';
274
+ import {
275
+ AnyProviderEvent,
276
+ EvaluationContext,
277
+ Hook,
278
+ JsonValue,
279
+ Logger,
280
+ Provider,
281
+ ProviderEventEmitter,
282
+ ProviderStatus,
283
+ ResolutionDetails
284
+ } from '@openfeature/server-sdk';
275
285
 
276
286
  // implement the provider interface
277
287
  class MyProvider implements Provider {
278
288
  // Adds runtime validation that the provider is used with the expected SDK
279
289
  public readonly runsOn = 'server';
280
-
281
290
  readonly metadata = {
282
291
  name: 'My Provider',
283
292
  } as const;
284
-
285
293
  // Optional provider managed hooks
286
- hooks?: Hook<FlagValue>[];
287
-
294
+ hooks?: Hook[];
288
295
  resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<boolean>> {
289
296
  // code to evaluate a boolean
290
297
  }
291
-
292
298
  resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<string>> {
293
299
  // code to evaluate a string
294
300
  }
295
-
296
301
  resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<number>> {
297
302
  // code to evaluate a number
298
303
  }
299
-
300
304
  resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext, logger: Logger): Promise<ResolutionDetails<T>> {
301
305
  // code to evaluate an object
302
306
  }
303
307
 
304
308
  status?: ProviderStatus | undefined;
305
- events?: OpenFeatureEventEmitter | undefined;
309
+
310
+ // implement with "new OpenFeatureEventEmitter()", and use "emit()" to emit events
311
+ events?: ProviderEventEmitter<AnyProviderEvent> | undefined;
306
312
 
307
313
  initialize?(context?: EvaluationContext | undefined): Promise<void> {
308
314
  // code to initialize your provider
309
315
  }
310
-
311
316
  onClose?(): Promise<void> {
312
317
  // code to shut down your provider
313
318
  }
package/dist/cjs/index.js CHANGED
@@ -81,11 +81,11 @@ var import_core3 = require("@openfeature/core");
81
81
 
82
82
  // src/provider/in-memory-provider/variant-not-found-error.ts
83
83
  var import_core2 = require("@openfeature/core");
84
- var VariantFoundError = class extends import_core2.OpenFeatureError {
84
+ var VariantFoundError = class _VariantFoundError extends import_core2.OpenFeatureError {
85
85
  code;
86
86
  constructor(message) {
87
87
  super(message);
88
- Object.setPrototypeOf(this, VariantFoundError.prototype);
88
+ Object.setPrototypeOf(this, _VariantFoundError.prototype);
89
89
  this.name = "VariantFoundError";
90
90
  this.code = import_core2.ErrorCode.GENERAL;
91
91
  }
@@ -196,7 +196,7 @@ var import_core5 = require("@openfeature/core");
196
196
  // src/open-feature.ts
197
197
  var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js-sdk/api");
198
198
  var _globalThis = globalThis;
199
- var OpenFeatureAPI = class extends import_core6.OpenFeatureCommonAPI {
199
+ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core6.OpenFeatureCommonAPI {
200
200
  _events = new OpenFeatureEventEmitter();
201
201
  _defaultProvider = NOOP_PROVIDER;
202
202
  _createEventEmitter = () => new OpenFeatureEventEmitter();
@@ -214,7 +214,7 @@ var OpenFeatureAPI = class extends import_core6.OpenFeatureCommonAPI {
214
214
  if (globalApi) {
215
215
  return globalApi;
216
216
  }
217
- const instance = new OpenFeatureAPI();
217
+ const instance = new _OpenFeatureAPI();
218
218
  _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
219
219
  return instance;
220
220
  }
@@ -225,15 +225,15 @@ var OpenFeatureAPI = class extends import_core6.OpenFeatureCommonAPI {
225
225
  getContext() {
226
226
  return this._context;
227
227
  }
228
- getClient(nameOrContext, versionOrContext, contextOrUndefined) {
229
- const name = (0, import_core6.stringOrUndefined)(nameOrContext);
228
+ getClient(domainOrContext, versionOrContext, contextOrUndefined) {
229
+ const domain = (0, import_core6.stringOrUndefined)(domainOrContext);
230
230
  const version = (0, import_core6.stringOrUndefined)(versionOrContext);
231
- const context = (0, import_core6.objectOrUndefined)(nameOrContext) ?? (0, import_core6.objectOrUndefined)(versionOrContext) ?? (0, import_core6.objectOrUndefined)(contextOrUndefined);
231
+ const context = (0, import_core6.objectOrUndefined)(domainOrContext) ?? (0, import_core6.objectOrUndefined)(versionOrContext) ?? (0, import_core6.objectOrUndefined)(contextOrUndefined);
232
232
  return new OpenFeatureClient(
233
- () => this.getProviderForClient(name),
234
- () => this.buildAndCacheEventEmitterForClient(name),
233
+ () => this.getProviderForClient(domain),
234
+ () => this.buildAndCacheEventEmitterForClient(domain),
235
235
  () => this._logger,
236
- { name, version },
236
+ { domain, version },
237
237
  context
238
238
  );
239
239
  }
@@ -285,7 +285,9 @@ var OpenFeatureClient = class {
285
285
  _clientLogger;
286
286
  get metadata() {
287
287
  return {
288
- name: this.options.name,
288
+ // Use domain if name is not provided
289
+ name: this.options.domain ?? this.options.name,
290
+ domain: this.options.domain ?? this.options.name,
289
291
  version: this.options.version,
290
292
  providerMetadata: this.providerAccessor().metadata
291
293
  };
@@ -295,7 +297,11 @@ var OpenFeatureClient = class {
295
297
  const shouldRunNow = (0, import_core7.statusMatchesEvent)(eventType, this._provider.status);
296
298
  if (shouldRunNow) {
297
299
  try {
298
- handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });
300
+ handler({
301
+ clientName: this.metadata.name,
302
+ domain: this.metadata.domain,
303
+ providerName: this._provider.metadata.name
304
+ });
299
305
  } catch (err) {
300
306
  this._logger?.error("Error running event handler:", err);
301
307
  }
@@ -485,6 +491,7 @@ __reExport(src_exports, require("@openfeature/core"), module.exports);
485
491
  OpenFeatureAPI,
486
492
  OpenFeatureClient,
487
493
  OpenFeatureEventEmitter,
488
- ProviderEvents
494
+ ProviderEvents,
495
+ ...require("@openfeature/core")
489
496
  });
490
497
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts", "../../src/client/open-feature-client.ts", "../../src/provider/no-op-provider.ts", "../../src/provider/in-memory-provider/in-memory-provider.ts", "../../src/provider/in-memory-provider/variant-not-found-error.ts", "../../src/open-feature.ts", "../../src/transaction-context/no-op-transaction-context-propagator.ts", "../../src/events/open-feature-event-emitter.ts", "../../src/events/events.ts"],
4
- "sourcesContent": ["export * from './client';\nexport * from './provider';\nexport * from './evaluation';\nexport * from './open-feature';\nexport * from './transaction-context';\nexport * from './events';\nexport * from './hooks';\nexport * from '@openfeature/core';\n", "import {\n ClientMetadata,\n ErrorCode,\n EvaluationContext,\n EvaluationDetails,\n EventHandler,\n FlagValue,\n FlagValueType,\n HookContext,\n JsonValue,\n Logger,\n ManageContext,\n OpenFeatureError,\n ResolutionDetails,\n SafeLogger,\n StandardResolutionReasons,\n statusMatchesEvent,\n} from '@openfeature/core';\nimport { FlagEvaluationOptions } from '../evaluation';\nimport { ProviderEvents } from '../events';\nimport { InternalEventEmitter } from '../events/internal/internal-event-emitter';\nimport { Hook } from '../hooks';\nimport { OpenFeature } from '../open-feature';\nimport { Provider } from '../provider';\nimport { Client } from './client';\n\ntype OpenFeatureClientOptions = {\n name?: string;\n version?: string;\n};\n\nexport class OpenFeatureClient implements Client, ManageContext<OpenFeatureClient> {\n private _context: EvaluationContext;\n private _hooks: Hook[] = [];\n private _clientLogger?: Logger;\n\n constructor(\n // we always want the client to use the current provider,\n // so pass a function to always access the currently registered one.\n private readonly providerAccessor: () => Provider,\n private readonly emitterAccessor: () => InternalEventEmitter,\n private readonly globalLogger: () => Logger,\n private readonly options: OpenFeatureClientOptions,\n context: EvaluationContext = {},\n ) {\n this._context = context;\n }\n\n get metadata(): ClientMetadata {\n return {\n name: this.options.name,\n version: this.options.version,\n providerMetadata: this.providerAccessor().metadata,\n };\n }\n\n addHandler(eventType: ProviderEvents, handler: EventHandler): void {\n this.emitterAccessor().addHandler(eventType, handler);\n const shouldRunNow = statusMatchesEvent(eventType, this._provider.status);\n\n if (shouldRunNow) {\n // run immediately, we're in the matching state\n try {\n handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });\n } catch (err) {\n this._logger?.error('Error running event handler:', err);\n }\n }\n }\n\n removeHandler(eventType: ProviderEvents, handler: EventHandler) {\n this.emitterAccessor().removeHandler(eventType, handler);\n }\n\n getHandlers(eventType: ProviderEvents) {\n return this.emitterAccessor().getHandlers(eventType);\n }\n\n setLogger(logger: Logger): OpenFeatureClient {\n this._clientLogger = new SafeLogger(logger);\n return this;\n }\n\n setContext(context: EvaluationContext): OpenFeatureClient {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n addHooks(...hooks: Hook[]): OpenFeatureClient {\n this._hooks = [...this._hooks, ...hooks];\n return this;\n }\n\n getHooks(): Hook[] {\n return this._hooks;\n }\n\n clearHooks(): OpenFeatureClient {\n this._hooks = [];\n return this;\n }\n\n async getBooleanValue(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<boolean> {\n return (await this.getBooleanDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getBooleanDetails(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<boolean>> {\n return this.evaluate<boolean>(\n flagKey,\n this._provider.resolveBooleanEvaluation,\n defaultValue,\n 'boolean',\n context,\n options,\n );\n }\n\n async getStringValue<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getStringDetails<T>(flagKey, defaultValue, context, options)).value;\n }\n\n getStringDetails<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted string generic argument.\n this._provider.resolveStringEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'string',\n context,\n options,\n );\n }\n\n async getNumberValue<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getNumberDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getNumberDetails<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted number generic argument.\n this._provider.resolveNumberEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'number',\n context,\n options,\n );\n }\n\n async getObjectValue<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getObjectDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getObjectDetails<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(flagKey, this._provider.resolveObjectEvaluation, defaultValue, 'object', context, options);\n }\n\n private async evaluate<T extends FlagValue>(\n flagKey: string,\n resolver: (\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n logger: Logger,\n ) => Promise<ResolutionDetails<T>>,\n defaultValue: T,\n flagType: FlagValueType,\n invocationContext: EvaluationContext = {},\n options: FlagEvaluationOptions = {},\n ): Promise<EvaluationDetails<T>> {\n // merge global, client, and evaluation context\n\n const allHooks = [\n ...OpenFeature.getHooks(),\n ...this.getHooks(),\n ...(options.hooks || []),\n ...(this._provider.hooks || []),\n ];\n const allHooksReversed = [...allHooks].reverse();\n\n // merge global and client contexts\n const mergedContext = {\n ...OpenFeature.getContext(),\n ...OpenFeature.getTransactionContext(),\n ...this._context,\n ...invocationContext,\n };\n\n // this reference cannot change during the course of evaluation\n // it may be used as a key in WeakMaps\n const hookContext: Readonly<HookContext> = {\n flagKey,\n defaultValue,\n flagValueType: flagType,\n clientMetadata: this.metadata,\n providerMetadata: OpenFeature.providerMetadata,\n context: mergedContext,\n logger: this._logger,\n };\n\n try {\n const frozenContext = await this.beforeHooks(allHooks, hookContext, options);\n\n // run the referenced resolver, binding the provider.\n const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);\n\n const evaluationDetails = {\n ...resolution,\n flagMetadata: Object.freeze(resolution.flagMetadata ?? {}),\n flagKey,\n };\n\n await this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);\n\n return evaluationDetails;\n } catch (err: unknown) {\n const errorMessage: string = (err as Error)?.message;\n const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;\n\n await this.errorHooks(allHooksReversed, hookContext, err, options);\n\n return {\n errorCode,\n errorMessage,\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n flagMetadata: Object.freeze({}),\n flagKey,\n };\n } finally {\n await this.finallyHooks(allHooksReversed, hookContext, options);\n }\n }\n\n private async beforeHooks(hooks: Hook[], hookContext: HookContext, options: FlagEvaluationOptions) {\n for (const hook of hooks) {\n // freeze the hookContext\n Object.freeze(hookContext);\n\n // use Object.assign to avoid modification of frozen hookContext\n Object.assign(hookContext.context, {\n ...hookContext.context,\n ...(await hook?.before?.(hookContext, Object.freeze(options.hookHints))),\n });\n }\n\n // after before hooks, freeze the EvaluationContext.\n return Object.freeze(hookContext.context);\n }\n\n private async afterHooks(\n hooks: Hook[],\n hookContext: HookContext,\n evaluationDetails: EvaluationDetails<FlagValue>,\n options: FlagEvaluationOptions,\n ) {\n // run \"after\" hooks sequentially\n for (const hook of hooks) {\n await hook?.after?.(hookContext, evaluationDetails, options.hookHints);\n }\n }\n\n private async errorHooks(hooks: Hook[], hookContext: HookContext, err: unknown, options: FlagEvaluationOptions) {\n // run \"error\" hooks sequentially\n for (const hook of hooks) {\n try {\n await hook?.error?.(hookContext, err, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'error' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private async finallyHooks(hooks: Hook[], hookContext: HookContext, options: FlagEvaluationOptions) {\n // run \"finally\" hooks sequentially\n for (const hook of hooks) {\n try {\n await hook?.finally?.(hookContext, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'finally' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private get _provider(): Provider {\n return this.providerAccessor();\n }\n\n private get _logger() {\n return this._clientLogger || this.globalLogger();\n }\n}\n", "import { ResolutionDetails, JsonValue, ProviderStatus } from '@openfeature/core';\nimport { Provider } from './provider';\n\nconst REASON_NO_OP = 'No-op';\n\n/**\n * The No-op provider is set by default, and simply always returns the default value.\n */\nclass NoopFeatureProvider implements Provider {\n readonly metadata = {\n name: 'No-op Provider',\n } as const;\n\n get status(): ProviderStatus {\n /**\n * This is due to the NoopProvider not being a real provider.\n * We do not want it to trigger the Ready event handlers, so we never set this to ready.\n * With the NoopProvider assigned, the client can be assumed to be uninitialized.\n * https://github.com/open-feature/js-sdk/pull/429#discussion_r1202642654\n */\n return ProviderStatus.NOT_READY;\n }\n\n resolveBooleanEvaluation(_: string, defaultValue: boolean): Promise<ResolutionDetails<boolean>> {\n return this.noOp(defaultValue);\n }\n\n resolveStringEvaluation(_: string, defaultValue: string): Promise<ResolutionDetails<string>> {\n return this.noOp(defaultValue);\n }\n\n resolveNumberEvaluation(_: string, defaultValue: number): Promise<ResolutionDetails<number>> {\n return this.noOp(defaultValue);\n }\n\n resolveObjectEvaluation<T extends JsonValue>(_: string, defaultValue: T): Promise<ResolutionDetails<T>> {\n return this.noOp<T>(defaultValue);\n }\n\n private noOp<T>(defaultValue: T) {\n return Promise.resolve({\n value: defaultValue,\n reason: REASON_NO_OP,\n });\n }\n}\n\nexport const NOOP_PROVIDER = new NoopFeatureProvider();\n", "import {\n EvaluationContext,\n FlagNotFoundError,\n FlagValueType,\n GeneralError,\n JsonValue,\n Logger,\n OpenFeatureError,\n ResolutionDetails,\n StandardResolutionReasons,\n TypeMismatchError\n} from '@openfeature/core';\nimport { Provider } from '../provider';\nimport { Flag, FlagConfiguration } from './flag-configuration';\nimport { VariantFoundError } from './variant-not-found-error';\nimport { OpenFeatureEventEmitter, ProviderEvents } from '../..';\n\n/**\n * A simple OpenFeature provider intended for demos and as a test stub.\n */\nexport class InMemoryProvider implements Provider {\n public readonly events = new OpenFeatureEventEmitter();\n public readonly runsOn = 'server';\n readonly metadata = {\n name: 'in-memory',\n } as const;\n private _flagConfiguration: FlagConfiguration;\n\n constructor(flagConfiguration: FlagConfiguration = {}) {\n this._flagConfiguration = { ...flagConfiguration };\n }\n\n /**\n * Overwrites the configured flags.\n * @param { FlagConfiguration } flagConfiguration new flag configuration\n */\n putConfiguration(flagConfiguration: FlagConfiguration) {\n const flagsChanged = Object.entries(flagConfiguration)\n .filter(([key, value]) => this._flagConfiguration[key] !== value)\n .map(([key]) => key);\n\n this._flagConfiguration = { ...flagConfiguration };\n this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged });\n }\n\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<boolean>> {\n return this.resolveFlagWithReason<boolean>(flagKey, defaultValue, context, logger);\n }\n\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<number>> {\n return this.resolveFlagWithReason<number>(flagKey, defaultValue, context, logger);\n }\n\n async resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<string>> {\n return this.resolveFlagWithReason<string>(flagKey, defaultValue, context, logger);\n }\n\n async resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n return this.resolveFlagWithReason<T>(flagKey, defaultValue, context, logger);\n }\n\n private async resolveFlagWithReason<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n try {\n const resolutionResult = this.lookupFlagValue(flagKey, defaultValue, ctx, logger);\n\n if (typeof resolutionResult?.value != typeof defaultValue) {\n throw new TypeMismatchError();\n }\n\n return resolutionResult;\n } catch (error: unknown) {\n if (!(error instanceof OpenFeatureError)) {\n throw new GeneralError((error as Error)?.message || 'unknown error'); \n }\n throw error;\n }\n }\n\n private lookupFlagValue<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): ResolutionDetails<T> {\n if (!(flagKey in this._flagConfiguration)) {\n const message = `no flag found with key ${flagKey}`;\n logger?.debug(message);\n throw new FlagNotFoundError(message);\n }\n const flagSpec: Flag = this._flagConfiguration[flagKey];\n\n if (flagSpec.disabled) {\n return { value: defaultValue, reason: StandardResolutionReasons.DISABLED };\n }\n\n const isContextEval = ctx && flagSpec?.contextEvaluator;\n const variant = isContextEval ? flagSpec.contextEvaluator?.(ctx) : flagSpec.defaultVariant;\n\n const value = variant && flagSpec?.variants[variant];\n\n if (value === undefined) {\n const message = `no value associated with variant ${variant}`;\n logger?.error(message);\n throw new VariantFoundError(message);\n }\n\n return {\n value: value as T,\n ...(variant && { variant }),\n reason: isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC,\n };\n }\n}\n", "import { ErrorCode, OpenFeatureError } from '@openfeature/core';\n\n/**\n * A custom error for the in-memory provider.\n * Indicates the resolved or default variant doesn't exist.\n */\nexport class VariantFoundError extends OpenFeatureError {\n code: ErrorCode;\n constructor(message?: string) {\n super(message);\n Object.setPrototypeOf(this, VariantFoundError.prototype);\n this.name = 'VariantFoundError';\n this.code = ErrorCode.GENERAL;\n }\n}\n", "import { NOOP_PROVIDER, Provider } from './provider';\nimport {\n ManageContext,\n OpenFeatureCommonAPI,\n EvaluationContext,\n objectOrUndefined,\n stringOrUndefined,\n} from '@openfeature/core';\nimport {\n ManageTransactionContextPropagator,\n NOOP_TRANSACTION_CONTEXT_PROPAGATOR,\n TransactionContext,\n TransactionContextPropagator,\n} from './transaction-context';\nimport { Client, OpenFeatureClient } from './client';\nimport { OpenFeatureEventEmitter } from './events';\nimport { Hook } from './hooks';\n\n// use a symbol as a key for the global singleton\nconst GLOBAL_OPENFEATURE_API_KEY = Symbol.for('@openfeature/js-sdk/api');\n\ntype OpenFeatureGlobal = {\n [GLOBAL_OPENFEATURE_API_KEY]?: OpenFeatureAPI;\n};\nconst _globalThis = globalThis as OpenFeatureGlobal;\n\nexport class OpenFeatureAPI\n extends OpenFeatureCommonAPI<Provider, Hook>\n implements ManageContext<OpenFeatureAPI>, ManageTransactionContextPropagator<OpenFeatureCommonAPI<Provider>>\n{\n protected _events = new OpenFeatureEventEmitter();\n protected _defaultProvider: Provider = NOOP_PROVIDER;\n protected _createEventEmitter = () => new OpenFeatureEventEmitter();\n\n private _transactionContextPropagator: TransactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;\n\n private constructor() {\n super('server');\n }\n\n /**\n * Gets a singleton instance of the OpenFeature API.\n * @ignore\n * @returns {OpenFeatureAPI} OpenFeature API\n */\n static getInstance(): OpenFeatureAPI {\n const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];\n if (globalApi) {\n return globalApi;\n }\n\n const instance = new OpenFeatureAPI();\n _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;\n return instance;\n }\n\n setContext(context: EvaluationContext): this {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n /**\n * A factory function for creating new unnamed OpenFeature clients. Clients can contain\n * their own state (e.g. logger, hook, context). Multiple clients can be used\n * to segment feature flag configuration.\n *\n * All unnamed clients use the same provider set via {@link this.setProvider setProvider}.\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(context?: EvaluationContext): Client;\n /**\n * A factory function for creating new named OpenFeature clients. Clients can contain\n * their own state (e.g. logger, hook, context). Multiple clients can be used\n * to segment feature flag configuration.\n *\n * If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that name.\n * @param {string} name The name of the client\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(name: string, context?: EvaluationContext): Client;\n /**\n * A factory function for creating new named OpenFeature clients. Clients can contain\n * their own state (e.g. logger, hook, context). Multiple clients can be used\n * to segment feature flag configuration.\n *\n * If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that name.\n * @param {string} name The name of the client\n * @param {string} version The version of the client (only used for metadata)\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(name: string, version: string, context?: EvaluationContext): Client;\n getClient(\n nameOrContext?: string | EvaluationContext,\n versionOrContext?: string | EvaluationContext,\n contextOrUndefined?: EvaluationContext,\n ): Client {\n const name = stringOrUndefined(nameOrContext);\n const version = stringOrUndefined(versionOrContext);\n const context =\n objectOrUndefined<EvaluationContext>(nameOrContext) ??\n objectOrUndefined<EvaluationContext>(versionOrContext) ??\n objectOrUndefined<EvaluationContext>(contextOrUndefined);\n\n return new OpenFeatureClient(\n () => this.getProviderForClient(name),\n () => this.buildAndCacheEventEmitterForClient(name),\n () => this._logger,\n { name, version },\n context,\n );\n }\n\n /**\n * Clears all registered providers and resets the default provider.\n * @returns {Promise<void>}\n */\n clearProviders(): Promise<void> {\n return super.clearProvidersAndSetDefault(NOOP_PROVIDER);\n }\n\n setTransactionContextPropagator(\n transactionContextPropagator: TransactionContextPropagator,\n ): OpenFeatureCommonAPI<Provider> {\n const baseMessage = 'Invalid TransactionContextPropagator, will not be set: ';\n if (typeof transactionContextPropagator?.getTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);\n } else if (typeof transactionContextPropagator?.setTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);\n } else {\n this._transactionContextPropagator = transactionContextPropagator;\n }\n return this;\n }\n\n setTransactionContext<R>(\n transactionContext: TransactionContext,\n callback: (...args: unknown[]) => R,\n ...args: unknown[]\n ): void {\n this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);\n }\n\n getTransactionContext(): TransactionContext {\n try {\n return this._transactionContextPropagator.getTransactionContext();\n } catch (err: unknown) {\n const error = err as Error | undefined;\n this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);\n this._logger.error(error?.stack);\n return {};\n }\n }\n}\n\n/**\n * A singleton instance of the OpenFeature API.\n * @returns {OpenFeatureAPI} OpenFeature API\n */\nexport const OpenFeature = OpenFeatureAPI.getInstance();\n", "import { EvaluationContext } from '@openfeature/core';\nimport { TransactionContextPropagator } from './transaction-context';\n\nclass NoopTransactionContextPropagator implements TransactionContextPropagator {\n getTransactionContext(): EvaluationContext {\n return {};\n }\n\n setTransactionContext(_: EvaluationContext, callback: () => void): void {\n callback();\n }\n}\n\nexport const NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();\n", "import { GenericEventEmitter } from '@openfeature/core';\nimport EventEmitter from 'events';\nimport { ProviderEvents } from './events';\n\n/**\n * The OpenFeatureEventEmitter can be used by provider developers to emit\n * events at various parts of the provider lifecycle.\n * \n * NOTE: Ready and error events are automatically emitted by the SDK based on\n * the result of the initialize method.\n */\nexport class OpenFeatureEventEmitter extends GenericEventEmitter<ProviderEvents> {\n protected readonly eventEmitter = new EventEmitter({ captureRejections: true });\n\n constructor() {\n super();\n this.eventEmitter.on('error', (err) => {\n this._logger?.error('Error running event handler:', err);\n });\n }\n};", "import { ServerProviderEvents } from '@openfeature/core';\n\nexport { ServerProviderEvents as ProviderEvents };"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAiBO;;;ACjBP,kBAA6D;AAG7D,IAAM,eAAe;AAKrB,IAAM,sBAAN,MAA8C;AAAA,EACnC,WAAW;AAAA,IAClB,MAAM;AAAA,EACR;AAAA,EAEA,IAAI,SAAyB;AAO3B,WAAO,2BAAe;AAAA,EACxB;AAAA,EAEA,yBAAyB,GAAW,cAA4D;AAC9F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAAwB,GAAW,cAA0D;AAC3F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAAwB,GAAW,cAA0D;AAC3F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAA6C,GAAW,cAAgD;AACtG,WAAO,KAAK,KAAQ,YAAY;AAAA,EAClC;AAAA,EAEQ,KAAQ,cAAiB;AAC/B,WAAO,QAAQ,QAAQ;AAAA,MACrB,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAEO,IAAM,gBAAgB,IAAI,oBAAoB;;;AC/CrD,IAAAC,eAWO;;;ACXP,IAAAC,eAA4C;AAMrC,IAAM,oBAAN,cAAgC,8BAAiB;AAAA,EACtD;AAAA,EACA,YAAY,SAAkB;AAC5B,UAAM,OAAO;AACb,WAAO,eAAe,MAAM,kBAAkB,SAAS;AACvD,SAAK,OAAO;AACZ,SAAK,OAAO,uBAAU;AAAA,EACxB;AACF;;;ADMO,IAAM,mBAAN,MAA2C;AAAA,EAChC,SAAS,IAAI,wBAAwB;AAAA,EACrC,SAAS;AAAA,EAChB,WAAW;AAAA,IAClB,MAAM;AAAA,EACR;AAAA,EACQ;AAAA,EAER,YAAY,oBAAuC,CAAC,GAAG;AACrD,SAAK,qBAAqB,EAAE,GAAG,kBAAkB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,mBAAsC;AACrD,UAAM,eAAe,OAAO,QAAQ,iBAAiB,EAClD,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,KAAK,mBAAmB,GAAG,MAAM,KAAK,EAC/D,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AAErB,SAAK,qBAAqB,EAAE,GAAG,kBAAkB;AACjD,SAAK,OAAO,KAAK,kCAAe,sBAAsB,EAAE,aAAa,CAAC;AAAA,EACxE;AAAA,EAEA,yBACE,SACA,cACA,SACA,QACqC;AACrC,WAAO,KAAK,sBAA+B,SAAS,cAAc,SAAS,MAAM;AAAA,EACnF;AAAA,EAEA,wBACE,SACA,cACA,SACA,QACoC;AACpC,WAAO,KAAK,sBAA8B,SAAS,cAAc,SAAS,MAAM;AAAA,EAClF;AAAA,EAEA,MAAM,wBACJ,SACA,cACA,SACA,QACoC;AACpC,WAAO,KAAK,sBAA8B,SAAS,cAAc,SAAS,MAAM;AAAA,EAClF;AAAA,EAEA,MAAM,wBACJ,SACA,cACA,SACA,QAC+B;AAC/B,WAAO,KAAK,sBAAyB,SAAS,cAAc,SAAS,MAAM;AAAA,EAC7E;AAAA,EAEA,MAAc,sBACZ,SACA,cACA,KACA,QAC+B;AAC/B,QAAI;AACF,YAAM,mBAAmB,KAAK,gBAAgB,SAAS,cAAc,KAAK,MAAM;AAEhF,UAAI,OAAO,kBAAkB,SAAS,OAAO,cAAc;AACzD,cAAM,IAAI,+BAAkB;AAAA,MAC9B;AAEA,aAAO;AAAA,IACT,SAAS,OAAP;AACA,UAAI,EAAE,iBAAiB,gCAAmB;AACxC,cAAM,IAAI,0BAAc,OAAiB,WAAW,eAAe;AAAA,MACrE;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,gBACN,SACA,cACA,KACA,QACsB;AACtB,QAAI,EAAE,WAAW,KAAK,qBAAqB;AACzC,YAAM,UAAU,0BAA0B;AAC1C,cAAQ,MAAM,OAAO;AACrB,YAAM,IAAI,+BAAkB,OAAO;AAAA,IACrC;AACA,UAAM,WAAiB,KAAK,mBAAmB,OAAO;AAEtD,QAAI,SAAS,UAAU;AACrB,aAAO,EAAE,OAAO,cAAc,QAAQ,uCAA0B,SAAS;AAAA,IAC3E;AAEA,UAAM,gBAAgB,OAAO,UAAU;AACvC,UAAM,UAAU,gBAAgB,SAAS,mBAAmB,GAAG,IAAI,SAAS;AAE5E,UAAM,QAAQ,WAAW,UAAU,SAAS,OAAO;AAEnD,QAAI,UAAU,QAAW;AACvB,YAAM,UAAU,oCAAoC;AACpD,cAAQ,MAAM,OAAO;AACrB,YAAM,IAAI,kBAAkB,OAAO;AAAA,IACrC;AAEA,WAAO;AAAA,MACL;AAAA,MACA,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,QAAQ,gBAAgB,uCAA0B,kBAAkB,uCAA0B;AAAA,IAChG;AAAA,EACF;AACF;;;AExIA,IAAAC,eAMO;;;ACJP,IAAM,mCAAN,MAA+E;AAAA,EAC7E,wBAA2C;AACzC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,sBAAsB,GAAsB,UAA4B;AACtE,aAAS;AAAA,EACX;AACF;AAEO,IAAM,sCAAsC,IAAI,iCAAiC;;;ACbxF,IAAAC,eAAoC;AACpC,oBAAyB;AAUlB,IAAM,0BAAN,cAAsC,iCAAoC;AAAA,EAC5D,eAAe,IAAI,cAAAC,QAAa,EAAE,mBAAmB,KAAK,CAAC;AAAA,EAE7E,cAAc;AACX,UAAM;AACN,SAAK,aAAa,GAAG,SAAS,CAAC,QAAQ;AACrC,WAAK,SAAS,MAAM,gCAAgC,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AACJ;;;ACpBA,IAAAC,eAAqC;;;AHmBrC,IAAM,6BAA6B,OAAO,IAAI,yBAAyB;AAKvE,IAAM,cAAc;AAEb,IAAM,iBAAN,cACG,kCAEV;AAAA,EACY,UAAU,IAAI,wBAAwB;AAAA,EACtC,mBAA6B;AAAA,EAC7B,sBAAsB,MAAM,IAAI,wBAAwB;AAAA,EAE1D,gCAA8D;AAAA,EAE9D,cAAc;AACpB,UAAM,QAAQ;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,cAA8B;AACnC,UAAM,YAAY,YAAY,0BAA0B;AACxD,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,IAAI,eAAe;AACpC,gBAAY,0BAA0B,IAAI;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,SAAkC;AAC3C,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAqCA,UACE,eACA,kBACA,oBACQ;AACR,UAAM,WAAO,gCAAkB,aAAa;AAC5C,UAAM,cAAU,gCAAkB,gBAAgB;AAClD,UAAM,cACJ,gCAAqC,aAAa,SAClD,gCAAqC,gBAAgB,SACrD,gCAAqC,kBAAkB;AAEzD,WAAO,IAAI;AAAA,MACT,MAAM,KAAK,qBAAqB,IAAI;AAAA,MACpC,MAAM,KAAK,mCAAmC,IAAI;AAAA,MAClD,MAAM,KAAK;AAAA,MACX,EAAE,MAAM,QAAQ;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAgC;AAC9B,WAAO,MAAM,4BAA4B,aAAa;AAAA,EACxD;AAAA,EAEA,gCACE,8BACgC;AAChC,UAAM,cAAc;AACpB,QAAI,OAAO,8BAA8B,0BAA0B,YAAY;AAC7E,WAAK,QAAQ,MAAM,GAAG,uDAAuD;AAAA,IAC/E,WAAW,OAAO,8BAA8B,0BAA0B,YAAY;AACpF,WAAK,QAAQ,MAAM,GAAG,uDAAuD;AAAA,IAC/E,OAAO;AACL,WAAK,gCAAgC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,sBACE,oBACA,aACG,MACG;AACN,SAAK,8BAA8B,sBAAsB,oBAAoB,UAAU,GAAG,IAAI;AAAA,EAChG;AAAA,EAEA,wBAA4C;AAC1C,QAAI;AACF,aAAO,KAAK,8BAA8B,sBAAsB;AAAA,IAClE,SAAS,KAAP;AACA,YAAM,QAAQ;AACd,WAAK,QAAQ,MAAM,sCAAsC,OAAO,mCAAmC;AACnG,WAAK,QAAQ,MAAM,OAAO,KAAK;AAC/B,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;AAMO,IAAM,cAAc,eAAe,YAAY;;;AJxI/C,IAAM,oBAAN,MAA4E;AAAA,EAKjF,YAGmB,kBACA,iBACA,cACA,SACjB,UAA6B,CAAC,GAC9B;AALiB;AACA;AACA;AACA;AAGjB,SAAK,WAAW;AAAA,EAClB;AAAA,EAdQ;AAAA,EACA,SAAiB,CAAC;AAAA,EAClB;AAAA,EAcR,IAAI,WAA2B;AAC7B,WAAO;AAAA,MACL,MAAM,KAAK,QAAQ;AAAA,MACnB,SAAS,KAAK,QAAQ;AAAA,MACtB,kBAAkB,KAAK,iBAAiB,EAAE;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,WAAW,WAA2B,SAA6B;AACjE,SAAK,gBAAgB,EAAE,WAAW,WAAW,OAAO;AACpD,UAAM,mBAAe,iCAAmB,WAAW,KAAK,UAAU,MAAM;AAExE,QAAI,cAAc;AAEhB,UAAI;AACF,gBAAQ,EAAE,YAAY,KAAK,SAAS,MAAM,cAAc,KAAK,UAAU,SAAS,KAAK,CAAC;AAAA,MACxF,SAAS,KAAP;AACA,aAAK,SAAS,MAAM,gCAAgC,GAAG;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,WAA2B,SAAuB;AAC9D,SAAK,gBAAgB,EAAE,cAAc,WAAW,OAAO;AAAA,EACzD;AAAA,EAEA,YAAY,WAA2B;AACrC,WAAO,KAAK,gBAAgB,EAAE,YAAY,SAAS;AAAA,EACrD;AAAA,EAEA,UAAU,QAAmC;AAC3C,SAAK,gBAAgB,IAAI,wBAAW,MAAM;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,SAA+C;AACxD,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,OAAkC;AAC5C,SAAK,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAgC;AAC9B,SAAK,SAAS,CAAC;AACf,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,SACA,cACA,SACA,SACkB;AAClB,YAAQ,MAAM,KAAK,kBAAkB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EACjF;AAAA,EAEA,kBACE,SACA,cACA,SACA,SACqC;AACrC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SACA,cACA,SACA,SACY;AACZ,YAAQ,MAAM,KAAK,iBAAoB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EACnF;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA;AAAA,MAEA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SACA,cACA,SACA,SACY;AACZ,YAAQ,MAAM,KAAK,iBAAiB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EAChF;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA;AAAA,MAEA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SACA,cACA,SACA,SACY;AACZ,YAAQ,MAAM,KAAK,iBAAiB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EAChF;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK,SAAY,SAAS,KAAK,UAAU,yBAAyB,cAAc,UAAU,SAAS,OAAO;AAAA,EACnH;AAAA,EAEA,MAAc,SACZ,SACA,UAMA,cACA,UACA,oBAAuC,CAAC,GACxC,UAAiC,CAAC,GACH;AAG/B,UAAM,WAAW;AAAA,MACf,GAAG,YAAY,SAAS;AAAA,MACxB,GAAG,KAAK,SAAS;AAAA,MACjB,GAAI,QAAQ,SAAS,CAAC;AAAA,MACtB,GAAI,KAAK,UAAU,SAAS,CAAC;AAAA,IAC/B;AACA,UAAM,mBAAmB,CAAC,GAAG,QAAQ,EAAE,QAAQ;AAG/C,UAAM,gBAAgB;AAAA,MACpB,GAAG,YAAY,WAAW;AAAA,MAC1B,GAAG,YAAY,sBAAsB;AAAA,MACrC,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL;AAIA,UAAM,cAAqC;AAAA,MACzC;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,YAAY;AAAA,MAC9B,SAAS;AAAA,MACT,QAAQ,KAAK;AAAA,IACf;AAEA,QAAI;AACF,YAAM,gBAAgB,MAAM,KAAK,YAAY,UAAU,aAAa,OAAO;AAG3E,YAAM,aAAa,MAAM,SAAS,KAAK,KAAK,WAAW,SAAS,cAAc,eAAe,KAAK,OAAO;AAEzG,YAAM,oBAAoB;AAAA,QACxB,GAAG;AAAA,QACH,cAAc,OAAO,OAAO,WAAW,gBAAgB,CAAC,CAAC;AAAA,QACzD;AAAA,MACF;AAEA,YAAM,KAAK,WAAW,kBAAkB,aAAa,mBAAmB,OAAO;AAE/E,aAAO;AAAA,IACT,SAAS,KAAP;AACA,YAAM,eAAwB,KAAe;AAC7C,YAAM,YAAwB,KAA0B,QAAQ,uBAAU;AAE1E,YAAM,KAAK,WAAW,kBAAkB,aAAa,KAAK,OAAO;AAEjE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ,uCAA0B;AAAA,QAClC,cAAc,OAAO,OAAO,CAAC,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,UAAE;AACA,YAAM,KAAK,aAAa,kBAAkB,aAAa,OAAO;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,OAAe,aAA0B,SAAgC;AACjG,eAAW,QAAQ,OAAO;AAExB,aAAO,OAAO,WAAW;AAGzB,aAAO,OAAO,YAAY,SAAS;AAAA,QACjC,GAAG,YAAY;AAAA,QACf,GAAI,MAAM,MAAM,SAAS,aAAa,OAAO,OAAO,QAAQ,SAAS,CAAC;AAAA,MACxE,CAAC;AAAA,IACH;AAGA,WAAO,OAAO,OAAO,YAAY,OAAO;AAAA,EAC1C;AAAA,EAEA,MAAc,WACZ,OACA,aACA,mBACA,SACA;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,MAAM,QAAQ,aAAa,mBAAmB,QAAQ,SAAS;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,MAAc,WAAW,OAAe,aAA0B,KAAc,SAAgC;AAE9G,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,MAAM,QAAQ,aAAa,KAAK,QAAQ,SAAS;AAAA,MACzD,SAASC,MAAP;AACA,aAAK,QAAQ,MAAM,wCAAwCA,MAAK;AAChE,YAAIA,gBAAe,OAAO;AACxB,eAAK,QAAQ,MAAMA,KAAI,KAAK;AAAA,QAC9B;AACA,aAAK,QAAQ,MAAOA,MAAe,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aAAa,OAAe,aAA0B,SAAgC;AAElG,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,MAAM,UAAU,aAAa,QAAQ,SAAS;AAAA,MACtD,SAAS,KAAP;AACA,aAAK,QAAQ,MAAM,0CAA0C,KAAK;AAClE,YAAI,eAAe,OAAO;AACxB,eAAK,QAAQ,MAAM,IAAI,KAAK;AAAA,QAC9B;AACA,aAAK,QAAQ,MAAO,KAAe,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAY,YAAsB;AAChC,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEA,IAAY,UAAU;AACpB,WAAO,KAAK,iBAAiB,KAAK,aAAa;AAAA,EACjD;AACF;;;ADhVA,wBAAc,8BAPd;",
4
+ "sourcesContent": ["export * from './client';\nexport * from './provider';\nexport * from './evaluation';\nexport * from './open-feature';\nexport * from './transaction-context';\nexport * from './events';\nexport * from './hooks';\nexport * from '@openfeature/core';\n", "import {\n ClientMetadata,\n ErrorCode,\n EvaluationContext,\n EvaluationDetails,\n EventHandler,\n FlagValue,\n FlagValueType,\n HookContext,\n JsonValue,\n Logger,\n ManageContext,\n OpenFeatureError,\n ResolutionDetails,\n SafeLogger,\n StandardResolutionReasons,\n statusMatchesEvent,\n} from '@openfeature/core';\nimport { FlagEvaluationOptions } from '../evaluation';\nimport { ProviderEvents } from '../events';\nimport { InternalEventEmitter } from '../events/internal/internal-event-emitter';\nimport { Hook } from '../hooks';\nimport { OpenFeature } from '../open-feature';\nimport { Provider } from '../provider';\nimport { Client } from './client';\n\ntype OpenFeatureClientOptions = {\n /**\n * @deprecated Use `domain` instead.\n */\n name?: string;\n domain?: string;\n version?: string;\n};\n\nexport class OpenFeatureClient implements Client, ManageContext<OpenFeatureClient> {\n private _context: EvaluationContext;\n private _hooks: Hook[] = [];\n private _clientLogger?: Logger;\n\n constructor(\n // we always want the client to use the current provider,\n // so pass a function to always access the currently registered one.\n private readonly providerAccessor: () => Provider,\n private readonly emitterAccessor: () => InternalEventEmitter,\n private readonly globalLogger: () => Logger,\n private readonly options: OpenFeatureClientOptions,\n context: EvaluationContext = {},\n ) {\n this._context = context;\n }\n\n get metadata(): ClientMetadata {\n return {\n // Use domain if name is not provided\n name: this.options.domain ?? this.options.name,\n domain: this.options.domain ?? this.options.name,\n version: this.options.version,\n providerMetadata: this.providerAccessor().metadata,\n };\n }\n\n addHandler(eventType: ProviderEvents, handler: EventHandler): void {\n this.emitterAccessor().addHandler(eventType, handler);\n const shouldRunNow = statusMatchesEvent(eventType, this._provider.status);\n\n if (shouldRunNow) {\n // run immediately, we're in the matching state\n try {\n handler({\n clientName: this.metadata.name,\n domain: this.metadata.domain,\n providerName: this._provider.metadata.name,\n });\n } catch (err) {\n this._logger?.error('Error running event handler:', err);\n }\n }\n }\n\n removeHandler(eventType: ProviderEvents, handler: EventHandler) {\n this.emitterAccessor().removeHandler(eventType, handler);\n }\n\n getHandlers(eventType: ProviderEvents) {\n return this.emitterAccessor().getHandlers(eventType);\n }\n\n setLogger(logger: Logger): OpenFeatureClient {\n this._clientLogger = new SafeLogger(logger);\n return this;\n }\n\n setContext(context: EvaluationContext): OpenFeatureClient {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n addHooks(...hooks: Hook[]): OpenFeatureClient {\n this._hooks = [...this._hooks, ...hooks];\n return this;\n }\n\n getHooks(): Hook[] {\n return this._hooks;\n }\n\n clearHooks(): OpenFeatureClient {\n this._hooks = [];\n return this;\n }\n\n async getBooleanValue(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<boolean> {\n return (await this.getBooleanDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getBooleanDetails(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<boolean>> {\n return this.evaluate<boolean>(\n flagKey,\n this._provider.resolveBooleanEvaluation,\n defaultValue,\n 'boolean',\n context,\n options,\n );\n }\n\n async getStringValue<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getStringDetails<T>(flagKey, defaultValue, context, options)).value;\n }\n\n getStringDetails<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted string generic argument.\n this._provider.resolveStringEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'string',\n context,\n options,\n );\n }\n\n async getNumberValue<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getNumberDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getNumberDetails<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(\n flagKey,\n // this isolates providers from our restricted number generic argument.\n this._provider.resolveNumberEvaluation as () => Promise<EvaluationDetails<T>>,\n defaultValue,\n 'number',\n context,\n options,\n );\n }\n\n async getObjectValue<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<T> {\n return (await this.getObjectDetails(flagKey, defaultValue, context, options)).value;\n }\n\n getObjectDetails<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n options?: FlagEvaluationOptions,\n ): Promise<EvaluationDetails<T>> {\n return this.evaluate<T>(flagKey, this._provider.resolveObjectEvaluation, defaultValue, 'object', context, options);\n }\n\n private async evaluate<T extends FlagValue>(\n flagKey: string,\n resolver: (\n flagKey: string,\n defaultValue: T,\n context: EvaluationContext,\n logger: Logger,\n ) => Promise<ResolutionDetails<T>>,\n defaultValue: T,\n flagType: FlagValueType,\n invocationContext: EvaluationContext = {},\n options: FlagEvaluationOptions = {},\n ): Promise<EvaluationDetails<T>> {\n // merge global, client, and evaluation context\n\n const allHooks = [\n ...OpenFeature.getHooks(),\n ...this.getHooks(),\n ...(options.hooks || []),\n ...(this._provider.hooks || []),\n ];\n const allHooksReversed = [...allHooks].reverse();\n\n // merge global and client contexts\n const mergedContext = {\n ...OpenFeature.getContext(),\n ...OpenFeature.getTransactionContext(),\n ...this._context,\n ...invocationContext,\n };\n\n // this reference cannot change during the course of evaluation\n // it may be used as a key in WeakMaps\n const hookContext: Readonly<HookContext> = {\n flagKey,\n defaultValue,\n flagValueType: flagType,\n clientMetadata: this.metadata,\n providerMetadata: OpenFeature.providerMetadata,\n context: mergedContext,\n logger: this._logger,\n };\n\n try {\n const frozenContext = await this.beforeHooks(allHooks, hookContext, options);\n\n // run the referenced resolver, binding the provider.\n const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);\n\n const evaluationDetails = {\n ...resolution,\n flagMetadata: Object.freeze(resolution.flagMetadata ?? {}),\n flagKey,\n };\n\n await this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);\n\n return evaluationDetails;\n } catch (err: unknown) {\n const errorMessage: string = (err as Error)?.message;\n const errorCode: ErrorCode = (err as OpenFeatureError)?.code || ErrorCode.GENERAL;\n\n await this.errorHooks(allHooksReversed, hookContext, err, options);\n\n return {\n errorCode,\n errorMessage,\n value: defaultValue,\n reason: StandardResolutionReasons.ERROR,\n flagMetadata: Object.freeze({}),\n flagKey,\n };\n } finally {\n await this.finallyHooks(allHooksReversed, hookContext, options);\n }\n }\n\n private async beforeHooks(hooks: Hook[], hookContext: HookContext, options: FlagEvaluationOptions) {\n for (const hook of hooks) {\n // freeze the hookContext\n Object.freeze(hookContext);\n\n // use Object.assign to avoid modification of frozen hookContext\n Object.assign(hookContext.context, {\n ...hookContext.context,\n ...(await hook?.before?.(hookContext, Object.freeze(options.hookHints))),\n });\n }\n\n // after before hooks, freeze the EvaluationContext.\n return Object.freeze(hookContext.context);\n }\n\n private async afterHooks(\n hooks: Hook[],\n hookContext: HookContext,\n evaluationDetails: EvaluationDetails<FlagValue>,\n options: FlagEvaluationOptions,\n ) {\n // run \"after\" hooks sequentially\n for (const hook of hooks) {\n await hook?.after?.(hookContext, evaluationDetails, options.hookHints);\n }\n }\n\n private async errorHooks(hooks: Hook[], hookContext: HookContext, err: unknown, options: FlagEvaluationOptions) {\n // run \"error\" hooks sequentially\n for (const hook of hooks) {\n try {\n await hook?.error?.(hookContext, err, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'error' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private async finallyHooks(hooks: Hook[], hookContext: HookContext, options: FlagEvaluationOptions) {\n // run \"finally\" hooks sequentially\n for (const hook of hooks) {\n try {\n await hook?.finally?.(hookContext, options.hookHints);\n } catch (err) {\n this._logger.error(`Unhandled error during 'finally' hook: ${err}`);\n if (err instanceof Error) {\n this._logger.error(err.stack);\n }\n this._logger.error((err as Error)?.stack);\n }\n }\n }\n\n private get _provider(): Provider {\n return this.providerAccessor();\n }\n\n private get _logger() {\n return this._clientLogger || this.globalLogger();\n }\n}\n", "import { ResolutionDetails, JsonValue, ProviderStatus } from '@openfeature/core';\nimport { Provider } from './provider';\n\nconst REASON_NO_OP = 'No-op';\n\n/**\n * The No-op provider is set by default, and simply always returns the default value.\n */\nclass NoopFeatureProvider implements Provider {\n readonly metadata = {\n name: 'No-op Provider',\n } as const;\n\n get status(): ProviderStatus {\n /**\n * This is due to the NoopProvider not being a real provider.\n * We do not want it to trigger the Ready event handlers, so we never set this to ready.\n * With the NoopProvider assigned, the client can be assumed to be uninitialized.\n * https://github.com/open-feature/js-sdk/pull/429#discussion_r1202642654\n */\n return ProviderStatus.NOT_READY;\n }\n\n resolveBooleanEvaluation(_: string, defaultValue: boolean): Promise<ResolutionDetails<boolean>> {\n return this.noOp(defaultValue);\n }\n\n resolveStringEvaluation(_: string, defaultValue: string): Promise<ResolutionDetails<string>> {\n return this.noOp(defaultValue);\n }\n\n resolveNumberEvaluation(_: string, defaultValue: number): Promise<ResolutionDetails<number>> {\n return this.noOp(defaultValue);\n }\n\n resolveObjectEvaluation<T extends JsonValue>(_: string, defaultValue: T): Promise<ResolutionDetails<T>> {\n return this.noOp<T>(defaultValue);\n }\n\n private noOp<T>(defaultValue: T) {\n return Promise.resolve({\n value: defaultValue,\n reason: REASON_NO_OP,\n });\n }\n}\n\nexport const NOOP_PROVIDER = new NoopFeatureProvider();\n", "import {\n EvaluationContext,\n FlagNotFoundError,\n FlagValueType,\n GeneralError,\n JsonValue,\n Logger,\n OpenFeatureError,\n ResolutionDetails,\n StandardResolutionReasons,\n TypeMismatchError\n} from '@openfeature/core';\nimport { Provider } from '../provider';\nimport { Flag, FlagConfiguration } from './flag-configuration';\nimport { VariantFoundError } from './variant-not-found-error';\nimport { OpenFeatureEventEmitter, ProviderEvents } from '../..';\n\n/**\n * A simple OpenFeature provider intended for demos and as a test stub.\n */\nexport class InMemoryProvider implements Provider {\n public readonly events = new OpenFeatureEventEmitter();\n public readonly runsOn = 'server';\n readonly metadata = {\n name: 'in-memory',\n } as const;\n private _flagConfiguration: FlagConfiguration;\n\n constructor(flagConfiguration: FlagConfiguration = {}) {\n this._flagConfiguration = { ...flagConfiguration };\n }\n\n /**\n * Overwrites the configured flags.\n * @param { FlagConfiguration } flagConfiguration new flag configuration\n */\n putConfiguration(flagConfiguration: FlagConfiguration) {\n const flagsChanged = Object.entries(flagConfiguration)\n .filter(([key, value]) => this._flagConfiguration[key] !== value)\n .map(([key]) => key);\n\n this._flagConfiguration = { ...flagConfiguration };\n this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged });\n }\n\n resolveBooleanEvaluation(\n flagKey: string,\n defaultValue: boolean,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<boolean>> {\n return this.resolveFlagWithReason<boolean>(flagKey, defaultValue, context, logger);\n }\n\n resolveNumberEvaluation(\n flagKey: string,\n defaultValue: number,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<number>> {\n return this.resolveFlagWithReason<number>(flagKey, defaultValue, context, logger);\n }\n\n async resolveStringEvaluation(\n flagKey: string,\n defaultValue: string,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<string>> {\n return this.resolveFlagWithReason<string>(flagKey, defaultValue, context, logger);\n }\n\n async resolveObjectEvaluation<T extends JsonValue>(\n flagKey: string,\n defaultValue: T,\n context?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n return this.resolveFlagWithReason<T>(flagKey, defaultValue, context, logger);\n }\n\n private async resolveFlagWithReason<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): Promise<ResolutionDetails<T>> {\n try {\n const resolutionResult = this.lookupFlagValue(flagKey, defaultValue, ctx, logger);\n\n if (typeof resolutionResult?.value != typeof defaultValue) {\n throw new TypeMismatchError();\n }\n\n return resolutionResult;\n } catch (error: unknown) {\n if (!(error instanceof OpenFeatureError)) {\n throw new GeneralError((error as Error)?.message || 'unknown error'); \n }\n throw error;\n }\n }\n\n private lookupFlagValue<T extends JsonValue | FlagValueType>(\n flagKey: string,\n defaultValue: T,\n ctx?: EvaluationContext,\n logger?: Logger,\n ): ResolutionDetails<T> {\n if (!(flagKey in this._flagConfiguration)) {\n const message = `no flag found with key ${flagKey}`;\n logger?.debug(message);\n throw new FlagNotFoundError(message);\n }\n const flagSpec: Flag = this._flagConfiguration[flagKey];\n\n if (flagSpec.disabled) {\n return { value: defaultValue, reason: StandardResolutionReasons.DISABLED };\n }\n\n const isContextEval = ctx && flagSpec?.contextEvaluator;\n const variant = isContextEval ? flagSpec.contextEvaluator?.(ctx) : flagSpec.defaultVariant;\n\n const value = variant && flagSpec?.variants[variant];\n\n if (value === undefined) {\n const message = `no value associated with variant ${variant}`;\n logger?.error(message);\n throw new VariantFoundError(message);\n }\n\n return {\n value: value as T,\n ...(variant && { variant }),\n reason: isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC,\n };\n }\n}\n", "import { ErrorCode, OpenFeatureError } from '@openfeature/core';\n\n/**\n * A custom error for the in-memory provider.\n * Indicates the resolved or default variant doesn't exist.\n */\nexport class VariantFoundError extends OpenFeatureError {\n code: ErrorCode;\n constructor(message?: string) {\n super(message);\n Object.setPrototypeOf(this, VariantFoundError.prototype);\n this.name = 'VariantFoundError';\n this.code = ErrorCode.GENERAL;\n }\n}\n", "import { NOOP_PROVIDER, Provider } from './provider';\nimport {\n ManageContext,\n OpenFeatureCommonAPI,\n EvaluationContext,\n objectOrUndefined,\n stringOrUndefined,\n} from '@openfeature/core';\nimport {\n ManageTransactionContextPropagator,\n NOOP_TRANSACTION_CONTEXT_PROPAGATOR,\n TransactionContext,\n TransactionContextPropagator,\n} from './transaction-context';\nimport { Client, OpenFeatureClient } from './client';\nimport { OpenFeatureEventEmitter } from './events';\nimport { Hook } from './hooks';\n\n// use a symbol as a key for the global singleton\nconst GLOBAL_OPENFEATURE_API_KEY = Symbol.for('@openfeature/js-sdk/api');\n\ntype OpenFeatureGlobal = {\n [GLOBAL_OPENFEATURE_API_KEY]?: OpenFeatureAPI;\n};\nconst _globalThis = globalThis as OpenFeatureGlobal;\n\nexport class OpenFeatureAPI\n extends OpenFeatureCommonAPI<Provider, Hook>\n implements ManageContext<OpenFeatureAPI>, ManageTransactionContextPropagator<OpenFeatureCommonAPI<Provider>>\n{\n protected _events = new OpenFeatureEventEmitter();\n protected _defaultProvider: Provider = NOOP_PROVIDER;\n protected _createEventEmitter = () => new OpenFeatureEventEmitter();\n\n private _transactionContextPropagator: TransactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;\n\n private constructor() {\n super('server');\n }\n\n /**\n * Gets a singleton instance of the OpenFeature API.\n * @ignore\n * @returns {OpenFeatureAPI} OpenFeature API\n */\n static getInstance(): OpenFeatureAPI {\n const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];\n if (globalApi) {\n return globalApi;\n }\n\n const instance = new OpenFeatureAPI();\n _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;\n return instance;\n }\n\n setContext(context: EvaluationContext): this {\n this._context = context;\n return this;\n }\n\n getContext(): EvaluationContext {\n return this._context;\n }\n\n /**\n * A factory function for creating new domainless OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * All domainless or unbound clients use the default provider set via {@link this.setProvider setProvider}.\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(context?: EvaluationContext): Client;\n /**\n * A factory function for creating new domain scoped OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * If there is already a provider bound to this domain via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that domain.\n * @param {string} domain An identifier which logically binds clients with providers\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(domain: string, context?: EvaluationContext): Client;\n /**\n * A factory function for creating new domain scoped OpenFeature clients.\n * Clients can contain their own state (e.g. logger, hook, context).\n * Multiple clients can be used to segment feature flag configuration.\n *\n * If there is already a provider bound to this domain via {@link this.setProvider setProvider}, this provider will be used.\n * Otherwise, the default provider is used until a provider is assigned to that domain.\n * @param {string} domain An identifier which logically binds clients with providers\n * @param {string} version The version of the client (only used for metadata)\n * @param {EvaluationContext} context Evaluation context that should be set on the client to used during flag evaluations\n * @returns {Client} OpenFeature Client\n */\n getClient(domain: string, version: string, context?: EvaluationContext): Client;\n getClient(\n domainOrContext?: string | EvaluationContext,\n versionOrContext?: string | EvaluationContext,\n contextOrUndefined?: EvaluationContext,\n ): Client {\n const domain = stringOrUndefined(domainOrContext);\n const version = stringOrUndefined(versionOrContext);\n const context =\n objectOrUndefined<EvaluationContext>(domainOrContext) ??\n objectOrUndefined<EvaluationContext>(versionOrContext) ??\n objectOrUndefined<EvaluationContext>(contextOrUndefined);\n\n return new OpenFeatureClient(\n () => this.getProviderForClient(domain),\n () => this.buildAndCacheEventEmitterForClient(domain),\n () => this._logger,\n { domain, version },\n context,\n );\n }\n\n /**\n * Clears all registered providers and resets the default provider.\n * @returns {Promise<void>}\n */\n clearProviders(): Promise<void> {\n return super.clearProvidersAndSetDefault(NOOP_PROVIDER);\n }\n\n setTransactionContextPropagator(\n transactionContextPropagator: TransactionContextPropagator,\n ): OpenFeatureCommonAPI<Provider> {\n const baseMessage = 'Invalid TransactionContextPropagator, will not be set: ';\n if (typeof transactionContextPropagator?.getTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);\n } else if (typeof transactionContextPropagator?.setTransactionContext !== 'function') {\n this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);\n } else {\n this._transactionContextPropagator = transactionContextPropagator;\n }\n return this;\n }\n\n setTransactionContext<R>(\n transactionContext: TransactionContext,\n callback: (...args: unknown[]) => R,\n ...args: unknown[]\n ): void {\n this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);\n }\n\n getTransactionContext(): TransactionContext {\n try {\n return this._transactionContextPropagator.getTransactionContext();\n } catch (err: unknown) {\n const error = err as Error | undefined;\n this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);\n this._logger.error(error?.stack);\n return {};\n }\n }\n}\n\n/**\n * A singleton instance of the OpenFeature API.\n * @returns {OpenFeatureAPI} OpenFeature API\n */\nexport const OpenFeature = OpenFeatureAPI.getInstance();\n", "import { EvaluationContext } from '@openfeature/core';\nimport { TransactionContextPropagator } from './transaction-context';\n\nclass NoopTransactionContextPropagator implements TransactionContextPropagator {\n getTransactionContext(): EvaluationContext {\n return {};\n }\n\n setTransactionContext(_: EvaluationContext, callback: () => void): void {\n callback();\n }\n}\n\nexport const NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();\n", "import { GenericEventEmitter } from '@openfeature/core';\nimport EventEmitter from 'events';\nimport { ProviderEvents } from './events';\n\n/**\n * The OpenFeatureEventEmitter can be used by provider developers to emit\n * events at various parts of the provider lifecycle.\n * \n * NOTE: Ready and error events are automatically emitted by the SDK based on\n * the result of the initialize method.\n */\nexport class OpenFeatureEventEmitter extends GenericEventEmitter<ProviderEvents> {\n protected readonly eventEmitter = new EventEmitter({ captureRejections: true });\n\n constructor() {\n super();\n this.eventEmitter.on('error', (err) => {\n this._logger?.error('Error running event handler:', err);\n });\n }\n};", "import { ServerProviderEvents } from '@openfeature/core';\n\nexport { ServerProviderEvents as ProviderEvents };"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAiBO;;;ACjBP,kBAA6D;AAG7D,IAAM,eAAe;AAKrB,IAAM,sBAAN,MAA8C;AAAA,EACnC,WAAW;AAAA,IAClB,MAAM;AAAA,EACR;AAAA,EAEA,IAAI,SAAyB;AAO3B,WAAO,2BAAe;AAAA,EACxB;AAAA,EAEA,yBAAyB,GAAW,cAA4D;AAC9F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAAwB,GAAW,cAA0D;AAC3F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAAwB,GAAW,cAA0D;AAC3F,WAAO,KAAK,KAAK,YAAY;AAAA,EAC/B;AAAA,EAEA,wBAA6C,GAAW,cAAgD;AACtG,WAAO,KAAK,KAAQ,YAAY;AAAA,EAClC;AAAA,EAEQ,KAAQ,cAAiB;AAC/B,WAAO,QAAQ,QAAQ;AAAA,MACrB,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACF;AAEO,IAAM,gBAAgB,IAAI,oBAAoB;;;AC/CrD,IAAAC,eAWO;;;ACXP,IAAAC,eAA4C;AAMrC,IAAM,oBAAN,MAAM,2BAA0B,8BAAiB;AAAA,EACtD;AAAA,EACA,YAAY,SAAkB;AAC5B,UAAM,OAAO;AACb,WAAO,eAAe,MAAM,mBAAkB,SAAS;AACvD,SAAK,OAAO;AACZ,SAAK,OAAO,uBAAU;AAAA,EACxB;AACF;;;ADMO,IAAM,mBAAN,MAA2C;AAAA,EAChC,SAAS,IAAI,wBAAwB;AAAA,EACrC,SAAS;AAAA,EAChB,WAAW;AAAA,IAClB,MAAM;AAAA,EACR;AAAA,EACQ;AAAA,EAER,YAAY,oBAAuC,CAAC,GAAG;AACrD,SAAK,qBAAqB,EAAE,GAAG,kBAAkB;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,mBAAsC;AACrD,UAAM,eAAe,OAAO,QAAQ,iBAAiB,EAClD,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,KAAK,mBAAmB,GAAG,MAAM,KAAK,EAC/D,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AAErB,SAAK,qBAAqB,EAAE,GAAG,kBAAkB;AACjD,SAAK,OAAO,KAAK,kCAAe,sBAAsB,EAAE,aAAa,CAAC;AAAA,EACxE;AAAA,EAEA,yBACE,SACA,cACA,SACA,QACqC;AACrC,WAAO,KAAK,sBAA+B,SAAS,cAAc,SAAS,MAAM;AAAA,EACnF;AAAA,EAEA,wBACE,SACA,cACA,SACA,QACoC;AACpC,WAAO,KAAK,sBAA8B,SAAS,cAAc,SAAS,MAAM;AAAA,EAClF;AAAA,EAEA,MAAM,wBACJ,SACA,cACA,SACA,QACoC;AACpC,WAAO,KAAK,sBAA8B,SAAS,cAAc,SAAS,MAAM;AAAA,EAClF;AAAA,EAEA,MAAM,wBACJ,SACA,cACA,SACA,QAC+B;AAC/B,WAAO,KAAK,sBAAyB,SAAS,cAAc,SAAS,MAAM;AAAA,EAC7E;AAAA,EAEA,MAAc,sBACZ,SACA,cACA,KACA,QAC+B;AAC/B,QAAI;AACF,YAAM,mBAAmB,KAAK,gBAAgB,SAAS,cAAc,KAAK,MAAM;AAEhF,UAAI,OAAO,kBAAkB,SAAS,OAAO,cAAc;AACzD,cAAM,IAAI,+BAAkB;AAAA,MAC9B;AAEA,aAAO;AAAA,IACT,SAAS,OAAgB;AACvB,UAAI,EAAE,iBAAiB,gCAAmB;AACxC,cAAM,IAAI,0BAAc,OAAiB,WAAW,eAAe;AAAA,MACrE;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,gBACN,SACA,cACA,KACA,QACsB;AACtB,QAAI,EAAE,WAAW,KAAK,qBAAqB;AACzC,YAAM,UAAU,0BAA0B,OAAO;AACjD,cAAQ,MAAM,OAAO;AACrB,YAAM,IAAI,+BAAkB,OAAO;AAAA,IACrC;AACA,UAAM,WAAiB,KAAK,mBAAmB,OAAO;AAEtD,QAAI,SAAS,UAAU;AACrB,aAAO,EAAE,OAAO,cAAc,QAAQ,uCAA0B,SAAS;AAAA,IAC3E;AAEA,UAAM,gBAAgB,OAAO,UAAU;AACvC,UAAM,UAAU,gBAAgB,SAAS,mBAAmB,GAAG,IAAI,SAAS;AAE5E,UAAM,QAAQ,WAAW,UAAU,SAAS,OAAO;AAEnD,QAAI,UAAU,QAAW;AACvB,YAAM,UAAU,oCAAoC,OAAO;AAC3D,cAAQ,MAAM,OAAO;AACrB,YAAM,IAAI,kBAAkB,OAAO;AAAA,IACrC;AAEA,WAAO;AAAA,MACL;AAAA,MACA,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,QAAQ,gBAAgB,uCAA0B,kBAAkB,uCAA0B;AAAA,IAChG;AAAA,EACF;AACF;;;AExIA,IAAAC,eAMO;;;ACJP,IAAM,mCAAN,MAA+E;AAAA,EAC7E,wBAA2C;AACzC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,sBAAsB,GAAsB,UAA4B;AACtE,aAAS;AAAA,EACX;AACF;AAEO,IAAM,sCAAsC,IAAI,iCAAiC;;;ACbxF,IAAAC,eAAoC;AACpC,oBAAyB;AAUlB,IAAM,0BAAN,cAAsC,iCAAoC;AAAA,EAC5D,eAAe,IAAI,cAAAC,QAAa,EAAE,mBAAmB,KAAK,CAAC;AAAA,EAE7E,cAAc;AACX,UAAM;AACN,SAAK,aAAa,GAAG,SAAS,CAAC,QAAQ;AACrC,WAAK,SAAS,MAAM,gCAAgC,GAAG;AAAA,IACzD,CAAC;AAAA,EACH;AACJ;;;ACpBA,IAAAC,eAAqC;;;AHmBrC,IAAM,6BAA6B,OAAO,IAAI,yBAAyB;AAKvE,IAAM,cAAc;AAEb,IAAM,iBAAN,MAAM,wBACH,kCAEV;AAAA,EACY,UAAU,IAAI,wBAAwB;AAAA,EACtC,mBAA6B;AAAA,EAC7B,sBAAsB,MAAM,IAAI,wBAAwB;AAAA,EAE1D,gCAA8D;AAAA,EAE9D,cAAc;AACpB,UAAM,QAAQ;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,cAA8B;AACnC,UAAM,YAAY,YAAY,0BAA0B;AACxD,QAAI,WAAW;AACb,aAAO;AAAA,IACT;AAEA,UAAM,WAAW,IAAI,gBAAe;AACpC,gBAAY,0BAA0B,IAAI;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,SAAkC;AAC3C,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAqCA,UACE,iBACA,kBACA,oBACQ;AACR,UAAM,aAAS,gCAAkB,eAAe;AAChD,UAAM,cAAU,gCAAkB,gBAAgB;AAClD,UAAM,cACJ,gCAAqC,eAAe,SACpD,gCAAqC,gBAAgB,SACrD,gCAAqC,kBAAkB;AAEzD,WAAO,IAAI;AAAA,MACT,MAAM,KAAK,qBAAqB,MAAM;AAAA,MACtC,MAAM,KAAK,mCAAmC,MAAM;AAAA,MACpD,MAAM,KAAK;AAAA,MACX,EAAE,QAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAgC;AAC9B,WAAO,MAAM,4BAA4B,aAAa;AAAA,EACxD;AAAA,EAEA,gCACE,8BACgC;AAChC,UAAM,cAAc;AACpB,QAAI,OAAO,8BAA8B,0BAA0B,YAAY;AAC7E,WAAK,QAAQ,MAAM,GAAG,WAAW,4CAA4C;AAAA,IAC/E,WAAW,OAAO,8BAA8B,0BAA0B,YAAY;AACpF,WAAK,QAAQ,MAAM,GAAG,WAAW,4CAA4C;AAAA,IAC/E,OAAO;AACL,WAAK,gCAAgC;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA,EAEA,sBACE,oBACA,aACG,MACG;AACN,SAAK,8BAA8B,sBAAsB,oBAAoB,UAAU,GAAG,IAAI;AAAA,EAChG;AAAA,EAEA,wBAA4C;AAC1C,QAAI;AACF,aAAO,KAAK,8BAA8B,sBAAsB;AAAA,IAClE,SAAS,KAAc;AACrB,YAAM,QAAQ;AACd,WAAK,QAAQ,MAAM,sCAAsC,OAAO,OAAO,4BAA4B;AACnG,WAAK,QAAQ,MAAM,OAAO,KAAK;AAC/B,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;AAMO,IAAM,cAAc,eAAe,YAAY;;;AJpI/C,IAAM,oBAAN,MAA4E;AAAA,EAKjF,YAGmB,kBACA,iBACA,cACA,SACjB,UAA6B,CAAC,GAC9B;AALiB;AACA;AACA;AACA;AAGjB,SAAK,WAAW;AAAA,EAClB;AAAA,EAdQ;AAAA,EACA,SAAiB,CAAC;AAAA,EAClB;AAAA,EAcR,IAAI,WAA2B;AAC7B,WAAO;AAAA;AAAA,MAEL,MAAM,KAAK,QAAQ,UAAU,KAAK,QAAQ;AAAA,MAC1C,QAAQ,KAAK,QAAQ,UAAU,KAAK,QAAQ;AAAA,MAC5C,SAAS,KAAK,QAAQ;AAAA,MACtB,kBAAkB,KAAK,iBAAiB,EAAE;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,WAAW,WAA2B,SAA6B;AACjE,SAAK,gBAAgB,EAAE,WAAW,WAAW,OAAO;AACpD,UAAM,mBAAe,iCAAmB,WAAW,KAAK,UAAU,MAAM;AAExE,QAAI,cAAc;AAEhB,UAAI;AACF,gBAAQ;AAAA,UACN,YAAY,KAAK,SAAS;AAAA,UAC1B,QAAQ,KAAK,SAAS;AAAA,UACtB,cAAc,KAAK,UAAU,SAAS;AAAA,QACxC,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,aAAK,SAAS,MAAM,gCAAgC,GAAG;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc,WAA2B,SAAuB;AAC9D,SAAK,gBAAgB,EAAE,cAAc,WAAW,OAAO;AAAA,EACzD;AAAA,EAEA,YAAY,WAA2B;AACrC,WAAO,KAAK,gBAAgB,EAAE,YAAY,SAAS;AAAA,EACrD;AAAA,EAEA,UAAU,QAAmC;AAC3C,SAAK,gBAAgB,IAAI,wBAAW,MAAM;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,SAA+C;AACxD,SAAK,WAAW;AAChB,WAAO;AAAA,EACT;AAAA,EAEA,aAAgC;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,OAAkC;AAC5C,SAAK,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAgC;AAC9B,SAAK,SAAS,CAAC;AACf,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,SACA,cACA,SACA,SACkB;AAClB,YAAQ,MAAM,KAAK,kBAAkB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EACjF;AAAA,EAEA,kBACE,SACA,cACA,SACA,SACqC;AACrC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SACA,cACA,SACA,SACY;AACZ,YAAQ,MAAM,KAAK,iBAAoB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EACnF;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA;AAAA,MAEA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SACA,cACA,SACA,SACY;AACZ,YAAQ,MAAM,KAAK,iBAAiB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EAChF;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK;AAAA,MACV;AAAA;AAAA,MAEA,KAAK,UAAU;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eACJ,SACA,cACA,SACA,SACY;AACZ,YAAQ,MAAM,KAAK,iBAAiB,SAAS,cAAc,SAAS,OAAO,GAAG;AAAA,EAChF;AAAA,EAEA,iBACE,SACA,cACA,SACA,SAC+B;AAC/B,WAAO,KAAK,SAAY,SAAS,KAAK,UAAU,yBAAyB,cAAc,UAAU,SAAS,OAAO;AAAA,EACnH;AAAA,EAEA,MAAc,SACZ,SACA,UAMA,cACA,UACA,oBAAuC,CAAC,GACxC,UAAiC,CAAC,GACH;AAG/B,UAAM,WAAW;AAAA,MACf,GAAG,YAAY,SAAS;AAAA,MACxB,GAAG,KAAK,SAAS;AAAA,MACjB,GAAI,QAAQ,SAAS,CAAC;AAAA,MACtB,GAAI,KAAK,UAAU,SAAS,CAAC;AAAA,IAC/B;AACA,UAAM,mBAAmB,CAAC,GAAG,QAAQ,EAAE,QAAQ;AAG/C,UAAM,gBAAgB;AAAA,MACpB,GAAG,YAAY,WAAW;AAAA,MAC1B,GAAG,YAAY,sBAAsB;AAAA,MACrC,GAAG,KAAK;AAAA,MACR,GAAG;AAAA,IACL;AAIA,UAAM,cAAqC;AAAA,MACzC;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,kBAAkB,YAAY;AAAA,MAC9B,SAAS;AAAA,MACT,QAAQ,KAAK;AAAA,IACf;AAEA,QAAI;AACF,YAAM,gBAAgB,MAAM,KAAK,YAAY,UAAU,aAAa,OAAO;AAG3E,YAAM,aAAa,MAAM,SAAS,KAAK,KAAK,WAAW,SAAS,cAAc,eAAe,KAAK,OAAO;AAEzG,YAAM,oBAAoB;AAAA,QACxB,GAAG;AAAA,QACH,cAAc,OAAO,OAAO,WAAW,gBAAgB,CAAC,CAAC;AAAA,QACzD;AAAA,MACF;AAEA,YAAM,KAAK,WAAW,kBAAkB,aAAa,mBAAmB,OAAO;AAE/E,aAAO;AAAA,IACT,SAAS,KAAc;AACrB,YAAM,eAAwB,KAAe;AAC7C,YAAM,YAAwB,KAA0B,QAAQ,uBAAU;AAE1E,YAAM,KAAK,WAAW,kBAAkB,aAAa,KAAK,OAAO;AAEjE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ,uCAA0B;AAAA,QAClC,cAAc,OAAO,OAAO,CAAC,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF,UAAE;AACA,YAAM,KAAK,aAAa,kBAAkB,aAAa,OAAO;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAc,YAAY,OAAe,aAA0B,SAAgC;AACjG,eAAW,QAAQ,OAAO;AAExB,aAAO,OAAO,WAAW;AAGzB,aAAO,OAAO,YAAY,SAAS;AAAA,QACjC,GAAG,YAAY;AAAA,QACf,GAAI,MAAM,MAAM,SAAS,aAAa,OAAO,OAAO,QAAQ,SAAS,CAAC;AAAA,MACxE,CAAC;AAAA,IACH;AAGA,WAAO,OAAO,OAAO,YAAY,OAAO;AAAA,EAC1C;AAAA,EAEA,MAAc,WACZ,OACA,aACA,mBACA,SACA;AAEA,eAAW,QAAQ,OAAO;AACxB,YAAM,MAAM,QAAQ,aAAa,mBAAmB,QAAQ,SAAS;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,MAAc,WAAW,OAAe,aAA0B,KAAc,SAAgC;AAE9G,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,MAAM,QAAQ,aAAa,KAAK,QAAQ,SAAS;AAAA,MACzD,SAASC,MAAK;AACZ,aAAK,QAAQ,MAAM,wCAAwCA,IAAG,EAAE;AAChE,YAAIA,gBAAe,OAAO;AACxB,eAAK,QAAQ,MAAMA,KAAI,KAAK;AAAA,QAC9B;AACA,aAAK,QAAQ,MAAOA,MAAe,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,aAAa,OAAe,aAA0B,SAAgC;AAElG,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,MAAM,UAAU,aAAa,QAAQ,SAAS;AAAA,MACtD,SAAS,KAAK;AACZ,aAAK,QAAQ,MAAM,0CAA0C,GAAG,EAAE;AAClE,YAAI,eAAe,OAAO;AACxB,eAAK,QAAQ,MAAM,IAAI,KAAK;AAAA,QAC9B;AACA,aAAK,QAAQ,MAAO,KAAe,KAAK;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAY,YAAsB;AAChC,WAAO,KAAK,iBAAiB;AAAA,EAC/B;AAAA,EAEA,IAAY,UAAU;AACpB,WAAO,KAAK,iBAAiB,KAAK,aAAa;AAAA,EACjD;AACF;;;AD1VA,wBAAc,8BAPd;",
6
6
  "names": ["import_core", "import_core", "import_core", "import_core", "import_core", "EventEmitter", "import_core", "err"]
7
7
  }
package/dist/esm/index.js CHANGED
@@ -48,11 +48,11 @@ import {
48
48
 
49
49
  // src/provider/in-memory-provider/variant-not-found-error.ts
50
50
  import { ErrorCode, OpenFeatureError } from "@openfeature/core";
51
- var VariantFoundError = class extends OpenFeatureError {
51
+ var VariantFoundError = class _VariantFoundError extends OpenFeatureError {
52
52
  code;
53
53
  constructor(message) {
54
54
  super(message);
55
- Object.setPrototypeOf(this, VariantFoundError.prototype);
55
+ Object.setPrototypeOf(this, _VariantFoundError.prototype);
56
56
  this.name = "VariantFoundError";
57
57
  this.code = ErrorCode.GENERAL;
58
58
  }
@@ -167,7 +167,7 @@ import { ServerProviderEvents } from "@openfeature/core";
167
167
  // src/open-feature.ts
168
168
  var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js-sdk/api");
169
169
  var _globalThis = globalThis;
170
- var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
170
+ var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
171
171
  _events = new OpenFeatureEventEmitter();
172
172
  _defaultProvider = NOOP_PROVIDER;
173
173
  _createEventEmitter = () => new OpenFeatureEventEmitter();
@@ -185,7 +185,7 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
185
185
  if (globalApi) {
186
186
  return globalApi;
187
187
  }
188
- const instance = new OpenFeatureAPI();
188
+ const instance = new _OpenFeatureAPI();
189
189
  _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
190
190
  return instance;
191
191
  }
@@ -196,15 +196,15 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
196
196
  getContext() {
197
197
  return this._context;
198
198
  }
199
- getClient(nameOrContext, versionOrContext, contextOrUndefined) {
200
- const name = stringOrUndefined(nameOrContext);
199
+ getClient(domainOrContext, versionOrContext, contextOrUndefined) {
200
+ const domain = stringOrUndefined(domainOrContext);
201
201
  const version = stringOrUndefined(versionOrContext);
202
- const context = objectOrUndefined(nameOrContext) ?? objectOrUndefined(versionOrContext) ?? objectOrUndefined(contextOrUndefined);
202
+ const context = objectOrUndefined(domainOrContext) ?? objectOrUndefined(versionOrContext) ?? objectOrUndefined(contextOrUndefined);
203
203
  return new OpenFeatureClient(
204
- () => this.getProviderForClient(name),
205
- () => this.buildAndCacheEventEmitterForClient(name),
204
+ () => this.getProviderForClient(domain),
205
+ () => this.buildAndCacheEventEmitterForClient(domain),
206
206
  () => this._logger,
207
- { name, version },
207
+ { domain, version },
208
208
  context
209
209
  );
210
210
  }
@@ -256,7 +256,9 @@ var OpenFeatureClient = class {
256
256
  _clientLogger;
257
257
  get metadata() {
258
258
  return {
259
- name: this.options.name,
259
+ // Use domain if name is not provided
260
+ name: this.options.domain ?? this.options.name,
261
+ domain: this.options.domain ?? this.options.name,
260
262
  version: this.options.version,
261
263
  providerMetadata: this.providerAccessor().metadata
262
264
  };
@@ -266,7 +268,11 @@ var OpenFeatureClient = class {
266
268
  const shouldRunNow = statusMatchesEvent(eventType, this._provider.status);
267
269
  if (shouldRunNow) {
268
270
  try {
269
- handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });
271
+ handler({
272
+ clientName: this.metadata.name,
273
+ domain: this.metadata.domain,
274
+ providerName: this._provider.metadata.name
275
+ });
270
276
  } catch (err) {
271
277
  this._logger?.error("Error running event handler:", err);
272
278
  }