@openfeature/web-sdk 0.3.2-experimental → 0.3.3-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/cjs/index.js CHANGED
@@ -94,22 +94,22 @@ var require_events = __commonJS({
94
94
  var NumberIsNaN = Number.isNaN || function NumberIsNaN2(value) {
95
95
  return value !== value;
96
96
  };
97
- function EventEmitter() {
98
- EventEmitter.init.call(this);
97
+ function EventEmitter2() {
98
+ EventEmitter2.init.call(this);
99
99
  }
100
- module2.exports = EventEmitter;
100
+ module2.exports = EventEmitter2;
101
101
  module2.exports.once = once;
102
- EventEmitter.EventEmitter = EventEmitter;
103
- EventEmitter.prototype._events = void 0;
104
- EventEmitter.prototype._eventsCount = 0;
105
- EventEmitter.prototype._maxListeners = void 0;
102
+ EventEmitter2.EventEmitter = EventEmitter2;
103
+ EventEmitter2.prototype._events = void 0;
104
+ EventEmitter2.prototype._eventsCount = 0;
105
+ EventEmitter2.prototype._maxListeners = void 0;
106
106
  var defaultMaxListeners = 10;
107
107
  function checkListener(listener) {
108
108
  if (typeof listener !== "function") {
109
109
  throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
110
110
  }
111
111
  }
112
- Object.defineProperty(EventEmitter, "defaultMaxListeners", {
112
+ Object.defineProperty(EventEmitter2, "defaultMaxListeners", {
113
113
  enumerable: true,
114
114
  get: function() {
115
115
  return defaultMaxListeners;
@@ -121,14 +121,14 @@ var require_events = __commonJS({
121
121
  defaultMaxListeners = arg;
122
122
  }
123
123
  });
124
- EventEmitter.init = function() {
124
+ EventEmitter2.init = function() {
125
125
  if (this._events === void 0 || this._events === Object.getPrototypeOf(this)._events) {
126
126
  this._events = /* @__PURE__ */ Object.create(null);
127
127
  this._eventsCount = 0;
128
128
  }
129
129
  this._maxListeners = this._maxListeners || void 0;
130
130
  };
131
- EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
131
+ EventEmitter2.prototype.setMaxListeners = function setMaxListeners(n) {
132
132
  if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) {
133
133
  throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + ".");
134
134
  }
@@ -137,13 +137,13 @@ var require_events = __commonJS({
137
137
  };
138
138
  function _getMaxListeners(that) {
139
139
  if (that._maxListeners === void 0)
140
- return EventEmitter.defaultMaxListeners;
140
+ return EventEmitter2.defaultMaxListeners;
141
141
  return that._maxListeners;
142
142
  }
143
- EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
143
+ EventEmitter2.prototype.getMaxListeners = function getMaxListeners() {
144
144
  return _getMaxListeners(this);
145
145
  };
146
- EventEmitter.prototype.emit = function emit(type) {
146
+ EventEmitter2.prototype.emit = function emit(type) {
147
147
  var args = [];
148
148
  for (var i = 1; i < arguments.length; i++)
149
149
  args.push(arguments[i]);
@@ -221,11 +221,11 @@ var require_events = __commonJS({
221
221
  }
222
222
  return target;
223
223
  }
224
- EventEmitter.prototype.addListener = function addListener(type, listener) {
224
+ EventEmitter2.prototype.addListener = function addListener(type, listener) {
225
225
  return _addListener(this, type, listener, false);
226
226
  };
227
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
228
- EventEmitter.prototype.prependListener = function prependListener(type, listener) {
227
+ EventEmitter2.prototype.on = EventEmitter2.prototype.addListener;
228
+ EventEmitter2.prototype.prependListener = function prependListener(type, listener) {
229
229
  return _addListener(this, type, listener, true);
230
230
  };
231
231
  function onceWrapper() {
@@ -244,17 +244,17 @@ var require_events = __commonJS({
244
244
  state.wrapFn = wrapped;
245
245
  return wrapped;
246
246
  }
247
- EventEmitter.prototype.once = function once2(type, listener) {
247
+ EventEmitter2.prototype.once = function once2(type, listener) {
248
248
  checkListener(listener);
249
249
  this.on(type, _onceWrap(this, type, listener));
250
250
  return this;
251
251
  };
252
- EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
252
+ EventEmitter2.prototype.prependOnceListener = function prependOnceListener(type, listener) {
253
253
  checkListener(listener);
254
254
  this.prependListener(type, _onceWrap(this, type, listener));
255
255
  return this;
256
256
  };
257
- EventEmitter.prototype.removeListener = function removeListener(type, listener) {
257
+ EventEmitter2.prototype.removeListener = function removeListener(type, listener) {
258
258
  var list, events, position, i, originalListener;
259
259
  checkListener(listener);
260
260
  events = this._events;
@@ -294,8 +294,8 @@ var require_events = __commonJS({
294
294
  }
295
295
  return this;
296
296
  };
297
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
298
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
297
+ EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
298
+ EventEmitter2.prototype.removeAllListeners = function removeAllListeners(type) {
299
299
  var listeners, events, i;
300
300
  events = this._events;
301
301
  if (events === void 0)
@@ -347,20 +347,20 @@ var require_events = __commonJS({
347
347
  return unwrap ? [evlistener.listener || evlistener] : [evlistener];
348
348
  return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
349
349
  }
350
- EventEmitter.prototype.listeners = function listeners(type) {
350
+ EventEmitter2.prototype.listeners = function listeners(type) {
351
351
  return _listeners(this, type, true);
352
352
  };
353
- EventEmitter.prototype.rawListeners = function rawListeners(type) {
353
+ EventEmitter2.prototype.rawListeners = function rawListeners(type) {
354
354
  return _listeners(this, type, false);
355
355
  };
356
- EventEmitter.listenerCount = function(emitter, type) {
356
+ EventEmitter2.listenerCount = function(emitter, type) {
357
357
  if (typeof emitter.listenerCount === "function") {
358
358
  return emitter.listenerCount(type);
359
359
  } else {
360
360
  return listenerCount.call(emitter, type);
361
361
  }
362
362
  };
363
- EventEmitter.prototype.listenerCount = listenerCount;
363
+ EventEmitter2.prototype.listenerCount = listenerCount;
364
364
  function listenerCount(type) {
365
365
  var events = this._events;
366
366
  if (events !== void 0) {
@@ -373,7 +373,7 @@ var require_events = __commonJS({
373
373
  }
374
374
  return 0;
375
375
  }
376
- EventEmitter.prototype.eventNames = function eventNames() {
376
+ EventEmitter2.prototype.eventNames = function eventNames() {
377
377
  return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
378
378
  };
379
379
  function arrayClone(arr, n) {
@@ -442,7 +442,6 @@ var require_events = __commonJS({
442
442
  // src/index.ts
443
443
  var src_exports = {};
444
444
  __export(src_exports, {
445
- ApiEvents: () => ApiEvents,
446
445
  DefaultLogger: () => DefaultLogger,
447
446
  ErrorCode: () => ErrorCode,
448
447
  FlagNotFoundError: () => FlagNotFoundError,
@@ -455,9 +454,10 @@ __export(src_exports, {
455
454
  OpenFeatureClient: () => OpenFeatureClient,
456
455
  OpenFeatureCommonAPI: () => OpenFeatureCommonAPI,
457
456
  OpenFeatureError: () => OpenFeatureError,
458
- OpenFeatureEventEmitter: () => import_events.EventEmitter,
457
+ OpenFeatureEventEmitter: () => OpenFeatureEventEmitter,
459
458
  ParseError: () => ParseError,
460
459
  ProviderEvents: () => ProviderEvents,
460
+ ProviderStatus: () => ProviderStatus,
461
461
  SafeLogger: () => SafeLogger,
462
462
  StandardResolutionReasons: () => StandardResolutionReasons,
463
463
  TargetingKeyMissingError: () => TargetingKeyMissingError,
@@ -480,7 +480,7 @@ var StandardResolutionReasons = {
480
480
  */
481
481
  DISABLED: "DISABLED",
482
482
  /**
483
- * The resolved value was configured statically, or otherwise fell back to a pre-configured value.
483
+ * The resolved value was configured statically, or otherwise fell back to a pre-configured value.
484
484
  */
485
485
  DEFAULT: "DEFAULT",
486
486
  /**
@@ -512,6 +512,12 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
512
512
  ErrorCode2["GENERAL"] = "GENERAL";
513
513
  return ErrorCode2;
514
514
  })(ErrorCode || {});
515
+ var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
516
+ ProviderStatus2["NOT_READY"] = "NOT_READY";
517
+ ProviderStatus2["READY"] = "READY";
518
+ ProviderStatus2["ERROR"] = "ERROR";
519
+ return ProviderStatus2;
520
+ })(ProviderStatus || {});
515
521
 
516
522
  // ../shared/src/errors/open-feature-error-abstract.ts
517
523
  var OpenFeatureError = class extends Error {
@@ -644,16 +650,217 @@ var NoopTransactionContextPropagator = class {
644
650
  };
645
651
  var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
646
652
 
653
+ // ../shared/src/events.ts
654
+ var import_events = __toESM(require_events());
655
+ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
656
+ ProviderEvents2["Ready"] = "PROVIDER_READY";
657
+ ProviderEvents2["Error"] = "PROVIDER_ERROR";
658
+ ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
659
+ ProviderEvents2["Stale"] = "PROVIDER_STALE";
660
+ return ProviderEvents2;
661
+ })(ProviderEvents || {});
662
+ var OpenFeatureEventEmitter = class {
663
+ constructor(globalLogger) {
664
+ this.globalLogger = globalLogger;
665
+ this._handlers = /* @__PURE__ */ new WeakMap();
666
+ this.eventEmitter = new import_events.default({ captureRejections: true });
667
+ this.eventEmitter.on("error", (err) => {
668
+ var _a;
669
+ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
670
+ });
671
+ }
672
+ emit(eventType, context) {
673
+ this.eventEmitter.emit(eventType, context);
674
+ }
675
+ addHandler(eventType, handler) {
676
+ const asyncHandler = (context) => __async(this, null, function* () {
677
+ yield handler(context);
678
+ });
679
+ this._handlers.set(handler, asyncHandler);
680
+ this.eventEmitter.on(eventType, asyncHandler);
681
+ }
682
+ removeHandler(eventType, handler) {
683
+ const asyncHandler = this._handlers.get(handler);
684
+ if (!asyncHandler) {
685
+ return;
686
+ }
687
+ this.eventEmitter.removeListener(eventType, asyncHandler);
688
+ }
689
+ removeAllHandlers(eventType) {
690
+ if (eventType) {
691
+ this.eventEmitter.removeAllListeners(eventType);
692
+ } else {
693
+ this.eventEmitter.removeAllListeners();
694
+ }
695
+ }
696
+ getHandlers(eventType) {
697
+ return this.eventEmitter.listeners(eventType);
698
+ }
699
+ setLogger(logger) {
700
+ this._eventLogger = new SafeLogger(logger);
701
+ return this;
702
+ }
703
+ get _logger() {
704
+ var _a;
705
+ return this._eventLogger || ((_a = this.globalLogger) == null ? void 0 : _a.call(this));
706
+ }
707
+ };
708
+
709
+ // ../shared/src/type-guards.ts
710
+ function isString(value) {
711
+ return typeof value === "string";
712
+ }
713
+ function stringOrUndefined(value) {
714
+ return isString(value) ? value : void 0;
715
+ }
716
+ function isObject(value) {
717
+ return typeof value === "object";
718
+ }
719
+ function objectOrUndefined(value) {
720
+ return isObject(value) ? value : void 0;
721
+ }
722
+
647
723
  // ../shared/src/open-feature.ts
648
724
  var OpenFeatureCommonAPI = class {
649
725
  constructor() {
650
726
  this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
651
727
  this._context = {};
652
728
  this._logger = new DefaultLogger();
729
+ this._events = new OpenFeatureEventEmitter(() => this._logger);
730
+ this._clientProviders = /* @__PURE__ */ new Map();
731
+ this._clientEvents = /* @__PURE__ */ new Map();
732
+ }
733
+ setLogger(logger) {
734
+ this._logger = new SafeLogger(logger);
735
+ return this;
736
+ }
737
+ /**
738
+ * Get metadata about registered provider.
739
+ * @returns {ProviderMetadata} Provider Metadata
740
+ */
741
+ get providerMetadata() {
742
+ return this._defaultProvider.metadata;
653
743
  }
654
744
  getContext() {
655
745
  return this._context;
656
746
  }
747
+ /**
748
+ * Adds a handler for the given provider event type.
749
+ * The handlers are called in the order they have been added.
750
+ * When changing the provider, the currently attached handlers will listen to the events of the new provider.
751
+ * @param {ProviderEvents} eventType The provider event type to listen to
752
+ * @param {EventHandler} handler The handler to run on occurrence of the event type
753
+ */
754
+ addHandler(eventType, handler) {
755
+ this._events.addHandler(eventType, handler);
756
+ }
757
+ /**
758
+ * Removes a handler for the given provider event type.
759
+ * @param {ProviderEvents} eventType The provider event type to remove the listener for
760
+ * @param {EventHandler} handler The handler to remove for the provider event type
761
+ */
762
+ removeHandler(eventType, handler) {
763
+ this._events.removeHandler(eventType, handler);
764
+ }
765
+ /**
766
+ * Gets the current handlers for the given provider event type.
767
+ * @param {ProviderEvents} eventType The provider event type to get the current handlers for
768
+ * @returns {EventHandler[]} The handlers currently attached to the given provider event type
769
+ */
770
+ getHandlers(eventType) {
771
+ return this._events.getHandlers(eventType);
772
+ }
773
+ setProvider(clientOrProvider, providerOrUndefined) {
774
+ var _a, _b, _c, _d, _e, _f;
775
+ const clientName = stringOrUndefined(clientOrProvider);
776
+ const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined);
777
+ if (!provider) {
778
+ return this;
779
+ }
780
+ const oldProvider = this.getProviderForClient(clientName);
781
+ if (oldProvider === provider) {
782
+ return this;
783
+ }
784
+ const clientEmitter = this.getEventEmitterForClient(clientName);
785
+ if (typeof provider.initialize === "function") {
786
+ (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => {
787
+ var _a2;
788
+ clientEmitter.emit("PROVIDER_READY" /* Ready */, { clientName });
789
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName });
790
+ })) == null ? void 0 : _d.catch((error) => {
791
+ var _a2;
792
+ clientEmitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
793
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
794
+ });
795
+ } else {
796
+ clientEmitter.emit("PROVIDER_READY" /* Ready */, { clientName });
797
+ (_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName });
798
+ }
799
+ if (clientName) {
800
+ this._clientProviders.set(clientName, provider);
801
+ } else {
802
+ this._defaultProvider = provider;
803
+ }
804
+ this.transferListeners(oldProvider, provider, clientName, clientEmitter);
805
+ if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) {
806
+ (_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider);
807
+ }
808
+ return this;
809
+ }
810
+ getProviderForClient(name) {
811
+ var _a;
812
+ if (!name) {
813
+ return this._defaultProvider;
814
+ }
815
+ return (_a = this._clientProviders.get(name)) != null ? _a : this._defaultProvider;
816
+ }
817
+ getEventEmitterForClient(name) {
818
+ const emitter = this._clientEvents.get(name);
819
+ if (emitter) {
820
+ return emitter;
821
+ }
822
+ const newEmitter = new OpenFeatureEventEmitter(() => this._logger);
823
+ this._clientEvents.set(name, newEmitter);
824
+ return newEmitter;
825
+ }
826
+ transferListeners(oldProvider, newProvider, clientName, clientEmitter) {
827
+ var _a;
828
+ (_a = oldProvider.events) == null ? void 0 : _a.removeAllHandlers();
829
+ Object.values(ProviderEvents).forEach(
830
+ (eventType) => {
831
+ var _a2;
832
+ return (_a2 = newProvider.events) == null ? void 0 : _a2.addHandler(eventType, (details) => __async(this, null, function* () {
833
+ clientEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
834
+ this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
835
+ }));
836
+ }
837
+ );
838
+ }
839
+ close() {
840
+ return __async(this, null, function* () {
841
+ var _a, _b;
842
+ try {
843
+ yield (_b = (_a = this == null ? void 0 : this._defaultProvider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a);
844
+ } catch (err) {
845
+ this.handleShutdownError(this._defaultProvider, err);
846
+ }
847
+ const providers = Array.from(this._clientProviders);
848
+ yield Promise.all(
849
+ providers.map((_0) => __async(this, [_0], function* ([, provider]) {
850
+ var _a2;
851
+ try {
852
+ yield (_a2 = provider.onClose) == null ? void 0 : _a2.call(provider);
853
+ } catch (err) {
854
+ this.handleShutdownError(this._defaultProvider, err);
855
+ }
856
+ }))
857
+ );
858
+ });
859
+ }
860
+ handleShutdownError(provider, err) {
861
+ this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`);
862
+ this._logger.error(err == null ? void 0 : err.stack);
863
+ }
657
864
  setTransactionContextPropagator(transactionContextPropagator) {
658
865
  const baseMessage = "Invalid TransactionContextPropagator, will not be set: ";
659
866
  if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.getTransactionContext) !== "function") {
@@ -688,6 +895,9 @@ var NoopFeatureProvider = class {
688
895
  name: "No-op Provider"
689
896
  };
690
897
  }
898
+ get status() {
899
+ return "NOT_READY" /* NOT_READY */;
900
+ }
691
901
  resolveBooleanEvaluation(_, defaultValue) {
692
902
  return this.noOp(defaultValue);
693
903
  }
@@ -709,35 +919,18 @@ var NoopFeatureProvider = class {
709
919
  };
710
920
  var NOOP_PROVIDER = new NoopFeatureProvider();
711
921
 
712
- // src/types.ts
713
- var import_events = __toESM(require_events());
714
- var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
715
- ProviderEvents2["Ready"] = "PROVIDER_READY";
716
- ProviderEvents2["Error"] = "PROVIDER_ERROR";
717
- ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
718
- ProviderEvents2["Stale"] = "PROVIDER_STALE";
719
- return ProviderEvents2;
720
- })(ProviderEvents || {});
721
- var ApiEvents = /* @__PURE__ */ ((ApiEvents2) => {
722
- ApiEvents2["ProviderChanged"] = "providerChanged";
723
- return ApiEvents2;
724
- })(ApiEvents || {});
725
-
726
922
  // src/open-feature.ts
727
- var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js.api");
923
+ var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/web-sdk/api");
728
924
  var _globalThis = globalThis;
729
925
  var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
730
926
  // eslint-disable-next-line @typescript-eslint/no-empty-function
731
927
  constructor() {
732
928
  super();
733
- this._apiEvents = new import_events.EventEmitter();
734
- this._providerReady = false;
735
929
  this._hooks = [];
736
- this._provider = NOOP_PROVIDER;
930
+ this._defaultProvider = NOOP_PROVIDER;
737
931
  }
738
932
  /**
739
933
  * Gets a singleton instance of the OpenFeature API.
740
- *
741
934
  * @ignore
742
935
  * @returns {OpenFeatureAPI} OpenFeature API
743
936
  */
@@ -750,14 +943,6 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
750
943
  _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
751
944
  return instance;
752
945
  }
753
- /**
754
- * Get metadata about registered provider.
755
- *
756
- * @returns {ProviderMetadata} Provider Metadata
757
- */
758
- get providerMetadata() {
759
- return this._provider.metadata;
760
- }
761
946
  setLogger(logger) {
762
947
  this._logger = new SafeLogger(logger);
763
948
  return this;
@@ -778,49 +963,26 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
778
963
  var _a, _b;
779
964
  const oldContext = this._context;
780
965
  this._context = context;
781
- yield (_b = (_a = this._provider) == null ? void 0 : _a.onContextChange) == null ? void 0 : _b.call(_a, oldContext, context);
782
- });
783
- }
784
- setProvider(provider) {
785
- var _a, _b, _c, _d, _e, _f, _g;
786
- if (this._provider !== provider) {
787
- const oldProvider = this._provider;
788
- this._provider = provider;
789
- this._providerReady = false;
790
- if (!this._provider.events) {
791
- this._provider.events = new import_events.EventEmitter();
792
- }
793
- if (typeof ((_a = this._provider) == null ? void 0 : _a.initialize) === "function") {
794
- (_e = (_d = (_c = (_b = this._provider).initialize) == null ? void 0 : _c.call(_b, this._context)) == null ? void 0 : _d.then(() => {
795
- var _a2;
796
- this._providerReady = true;
797
- (_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */);
798
- })) == null ? void 0 : _e.catch(() => {
799
- var _a2;
800
- (_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */);
801
- });
802
- } else {
803
- this._providerReady = true;
804
- (_f = this._provider.events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */);
805
- }
806
- this._apiEvents.emit("providerChanged" /* ProviderChanged */);
807
- (_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider);
808
- }
809
- return this;
810
- }
811
- close() {
812
- return __async(this, null, function* () {
813
- var _a, _b;
814
- yield (_b = (_a = this == null ? void 0 : this._provider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a);
966
+ yield (_b = (_a = this._defaultProvider) == null ? void 0 : _a.onContextChange) == null ? void 0 : _b.call(_a, oldContext, context);
815
967
  });
816
968
  }
969
+ /**
970
+ * A factory function for creating new named OpenFeature clients. Clients can contain
971
+ * their own state (e.g. logger, hook, context). Multiple clients can be used
972
+ * to segment feature flag configuration.
973
+ *
974
+ * If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.
975
+ * Otherwise, the default provider is used until a provider is assigned to that name.
976
+ * @param {string} name The name of the client
977
+ * @param {string} version The version of the client (only used for metadata)
978
+ * @returns {Client} OpenFeature Client
979
+ */
817
980
  getClient(name, version) {
818
981
  return new OpenFeatureClient(
819
982
  // functions are passed here to make sure that these values are always up to date,
820
983
  // and so we don't have to make these public properties on the API class.
821
- () => this._provider,
822
- () => this._providerReady,
823
- () => this._apiEvents,
984
+ () => this.getProviderForClient(name),
985
+ () => this.getEventEmitterForClient(name),
824
986
  () => this._logger,
825
987
  { name, version }
826
988
  );
@@ -830,27 +992,33 @@ var OpenFeature = OpenFeatureAPI.getInstance();
830
992
 
831
993
  // src/client.ts
832
994
  var OpenFeatureClient = class {
833
- constructor(providerAccessor, providerReady, apiEvents, globalLogger, options) {
995
+ constructor(providerAccessor, events, globalLogger, options) {
834
996
  this.providerAccessor = providerAccessor;
835
- this.providerReady = providerReady;
997
+ this.events = events;
836
998
  this.globalLogger = globalLogger;
999
+ this.options = options;
837
1000
  this._hooks = [];
838
- this._handlerWrappers = [];
839
- this.metadata = {
840
- name: options.name,
841
- version: options.version
1001
+ }
1002
+ get metadata() {
1003
+ return {
1004
+ name: this.options.name,
1005
+ version: this.options.version,
1006
+ providerMetadata: this.providerAccessor().metadata
842
1007
  };
843
- this.attachListeners();
844
- apiEvents().on("providerChanged" /* ProviderChanged */, () => {
845
- this.attachListeners();
846
- });
847
1008
  }
848
1009
  addHandler(eventType, handler) {
849
- this._handlerWrappers.push({ eventType, handler });
850
- if (eventType === "PROVIDER_READY" /* Ready */ && this.providerReady()) {
851
- handler();
1010
+ this.events().addHandler(eventType, handler);
1011
+ const providerReady = !this._provider.status || this._provider.status === "READY" /* READY */;
1012
+ if (eventType === "PROVIDER_READY" /* Ready */ && providerReady) {
1013
+ handler({ clientName: this.metadata.name });
852
1014
  }
853
1015
  }
1016
+ removeHandler(notificationType, handler) {
1017
+ this.events().removeHandler(notificationType, handler);
1018
+ }
1019
+ getHandlers(eventType) {
1020
+ return this.events().getHandlers(eventType);
1021
+ }
854
1022
  setLogger(logger) {
855
1023
  this._clientLogger = new SafeLogger(logger);
856
1024
  return this;
@@ -870,13 +1038,7 @@ var OpenFeatureClient = class {
870
1038
  return this.getBooleanDetails(flagKey, defaultValue, options).value;
871
1039
  }
872
1040
  getBooleanDetails(flagKey, defaultValue, options) {
873
- return this.evaluate(
874
- flagKey,
875
- this._provider.resolveBooleanEvaluation,
876
- defaultValue,
877
- "boolean",
878
- options
879
- );
1041
+ return this.evaluate(flagKey, this._provider.resolveBooleanEvaluation, defaultValue, "boolean", options);
880
1042
  }
881
1043
  getStringValue(flagKey, defaultValue, options) {
882
1044
  return this.getStringDetails(flagKey, defaultValue, options).value;
@@ -911,6 +1073,7 @@ var OpenFeatureClient = class {
911
1073
  return this.evaluate(flagKey, this._provider.resolveObjectEvaluation, defaultValue, "object", options);
912
1074
  }
913
1075
  evaluate(flagKey, resolver, defaultValue, flagType, options = {}) {
1076
+ var _a;
914
1077
  const allHooks = [
915
1078
  ...OpenFeature.getHooks(),
916
1079
  ...this.getHooks(),
@@ -932,6 +1095,7 @@ var OpenFeatureClient = class {
932
1095
  this.beforeHooks(allHooks, hookContext, options);
933
1096
  const resolution = resolver.call(this._provider, flagKey, defaultValue, context, this._logger);
934
1097
  const evaluationDetails = __spreadProps(__spreadValues({}, resolution), {
1098
+ flagMetadata: Object.freeze((_a = resolution.flagMetadata) != null ? _a : {}),
935
1099
  flagKey
936
1100
  });
937
1101
  this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
@@ -945,6 +1109,7 @@ var OpenFeatureClient = class {
945
1109
  errorMessage,
946
1110
  value: defaultValue,
947
1111
  reason: StandardResolutionReasons.ERROR,
1112
+ flagMetadata: Object.freeze({}),
948
1113
  flagKey
949
1114
  };
950
1115
  } finally {
@@ -999,13 +1164,5 @@ var OpenFeatureClient = class {
999
1164
  get _logger() {
1000
1165
  return this._clientLogger || this.globalLogger();
1001
1166
  }
1002
- attachListeners() {
1003
- Object.values(ProviderEvents).forEach((eventType) => {
1004
- var _a;
1005
- return (_a = this._provider.events) == null ? void 0 : _a.on(eventType, () => {
1006
- this._handlerWrappers.filter((wrapper) => wrapper.eventType === eventType).forEach((wrapper) => wrapper.handler());
1007
- });
1008
- });
1009
- }
1010
1167
  };
1011
1168
  //# sourceMappingURL=index.js.map