@openfeature/web-sdk 0.3.2-experimental → 0.3.4-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/esm/index.js CHANGED
@@ -88,22 +88,22 @@ var require_events = __commonJS({
88
88
  var NumberIsNaN = Number.isNaN || function NumberIsNaN2(value) {
89
89
  return value !== value;
90
90
  };
91
- function EventEmitter() {
92
- EventEmitter.init.call(this);
91
+ function EventEmitter2() {
92
+ EventEmitter2.init.call(this);
93
93
  }
94
- module.exports = EventEmitter;
94
+ module.exports = EventEmitter2;
95
95
  module.exports.once = once;
96
- EventEmitter.EventEmitter = EventEmitter;
97
- EventEmitter.prototype._events = void 0;
98
- EventEmitter.prototype._eventsCount = 0;
99
- EventEmitter.prototype._maxListeners = void 0;
96
+ EventEmitter2.EventEmitter = EventEmitter2;
97
+ EventEmitter2.prototype._events = void 0;
98
+ EventEmitter2.prototype._eventsCount = 0;
99
+ EventEmitter2.prototype._maxListeners = void 0;
100
100
  var defaultMaxListeners = 10;
101
101
  function checkListener(listener) {
102
102
  if (typeof listener !== "function") {
103
103
  throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
104
104
  }
105
105
  }
106
- Object.defineProperty(EventEmitter, "defaultMaxListeners", {
106
+ Object.defineProperty(EventEmitter2, "defaultMaxListeners", {
107
107
  enumerable: true,
108
108
  get: function() {
109
109
  return defaultMaxListeners;
@@ -115,14 +115,14 @@ var require_events = __commonJS({
115
115
  defaultMaxListeners = arg;
116
116
  }
117
117
  });
118
- EventEmitter.init = function() {
118
+ EventEmitter2.init = function() {
119
119
  if (this._events === void 0 || this._events === Object.getPrototypeOf(this)._events) {
120
120
  this._events = /* @__PURE__ */ Object.create(null);
121
121
  this._eventsCount = 0;
122
122
  }
123
123
  this._maxListeners = this._maxListeners || void 0;
124
124
  };
125
- EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
125
+ EventEmitter2.prototype.setMaxListeners = function setMaxListeners(n) {
126
126
  if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) {
127
127
  throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + ".");
128
128
  }
@@ -131,13 +131,13 @@ var require_events = __commonJS({
131
131
  };
132
132
  function _getMaxListeners(that) {
133
133
  if (that._maxListeners === void 0)
134
- return EventEmitter.defaultMaxListeners;
134
+ return EventEmitter2.defaultMaxListeners;
135
135
  return that._maxListeners;
136
136
  }
137
- EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
137
+ EventEmitter2.prototype.getMaxListeners = function getMaxListeners() {
138
138
  return _getMaxListeners(this);
139
139
  };
140
- EventEmitter.prototype.emit = function emit(type) {
140
+ EventEmitter2.prototype.emit = function emit(type) {
141
141
  var args = [];
142
142
  for (var i = 1; i < arguments.length; i++)
143
143
  args.push(arguments[i]);
@@ -215,11 +215,11 @@ var require_events = __commonJS({
215
215
  }
216
216
  return target;
217
217
  }
218
- EventEmitter.prototype.addListener = function addListener(type, listener) {
218
+ EventEmitter2.prototype.addListener = function addListener(type, listener) {
219
219
  return _addListener(this, type, listener, false);
220
220
  };
221
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
222
- EventEmitter.prototype.prependListener = function prependListener(type, listener) {
221
+ EventEmitter2.prototype.on = EventEmitter2.prototype.addListener;
222
+ EventEmitter2.prototype.prependListener = function prependListener(type, listener) {
223
223
  return _addListener(this, type, listener, true);
224
224
  };
225
225
  function onceWrapper() {
@@ -238,17 +238,17 @@ var require_events = __commonJS({
238
238
  state.wrapFn = wrapped;
239
239
  return wrapped;
240
240
  }
241
- EventEmitter.prototype.once = function once2(type, listener) {
241
+ EventEmitter2.prototype.once = function once2(type, listener) {
242
242
  checkListener(listener);
243
243
  this.on(type, _onceWrap(this, type, listener));
244
244
  return this;
245
245
  };
246
- EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
246
+ EventEmitter2.prototype.prependOnceListener = function prependOnceListener(type, listener) {
247
247
  checkListener(listener);
248
248
  this.prependListener(type, _onceWrap(this, type, listener));
249
249
  return this;
250
250
  };
251
- EventEmitter.prototype.removeListener = function removeListener(type, listener) {
251
+ EventEmitter2.prototype.removeListener = function removeListener(type, listener) {
252
252
  var list, events, position, i, originalListener;
253
253
  checkListener(listener);
254
254
  events = this._events;
@@ -288,8 +288,8 @@ var require_events = __commonJS({
288
288
  }
289
289
  return this;
290
290
  };
291
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
292
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
291
+ EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
292
+ EventEmitter2.prototype.removeAllListeners = function removeAllListeners(type) {
293
293
  var listeners, events, i;
294
294
  events = this._events;
295
295
  if (events === void 0)
@@ -341,20 +341,20 @@ var require_events = __commonJS({
341
341
  return unwrap ? [evlistener.listener || evlistener] : [evlistener];
342
342
  return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
343
343
  }
344
- EventEmitter.prototype.listeners = function listeners(type) {
344
+ EventEmitter2.prototype.listeners = function listeners(type) {
345
345
  return _listeners(this, type, true);
346
346
  };
347
- EventEmitter.prototype.rawListeners = function rawListeners(type) {
347
+ EventEmitter2.prototype.rawListeners = function rawListeners(type) {
348
348
  return _listeners(this, type, false);
349
349
  };
350
- EventEmitter.listenerCount = function(emitter, type) {
350
+ EventEmitter2.listenerCount = function(emitter, type) {
351
351
  if (typeof emitter.listenerCount === "function") {
352
352
  return emitter.listenerCount(type);
353
353
  } else {
354
354
  return listenerCount.call(emitter, type);
355
355
  }
356
356
  };
357
- EventEmitter.prototype.listenerCount = listenerCount;
357
+ EventEmitter2.prototype.listenerCount = listenerCount;
358
358
  function listenerCount(type) {
359
359
  var events = this._events;
360
360
  if (events !== void 0) {
@@ -367,7 +367,7 @@ var require_events = __commonJS({
367
367
  }
368
368
  return 0;
369
369
  }
370
- EventEmitter.prototype.eventNames = function eventNames() {
370
+ EventEmitter2.prototype.eventNames = function eventNames() {
371
371
  return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
372
372
  };
373
373
  function arrayClone(arr, n) {
@@ -448,7 +448,7 @@ var StandardResolutionReasons = {
448
448
  */
449
449
  DISABLED: "DISABLED",
450
450
  /**
451
- * The resolved value was configured statically, or otherwise fell back to a pre-configured value.
451
+ * The resolved value was configured statically, or otherwise fell back to a pre-configured value.
452
452
  */
453
453
  DEFAULT: "DEFAULT",
454
454
  /**
@@ -480,6 +480,12 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
480
480
  ErrorCode2["GENERAL"] = "GENERAL";
481
481
  return ErrorCode2;
482
482
  })(ErrorCode || {});
483
+ var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
484
+ ProviderStatus2["NOT_READY"] = "NOT_READY";
485
+ ProviderStatus2["READY"] = "READY";
486
+ ProviderStatus2["ERROR"] = "ERROR";
487
+ return ProviderStatus2;
488
+ })(ProviderStatus || {});
483
489
 
484
490
  // ../shared/src/errors/open-feature-error-abstract.ts
485
491
  var OpenFeatureError = class extends Error {
@@ -612,16 +618,217 @@ var NoopTransactionContextPropagator = class {
612
618
  };
613
619
  var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
614
620
 
621
+ // ../shared/src/events.ts
622
+ var import_events = __toESM(require_events());
623
+ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
624
+ ProviderEvents2["Ready"] = "PROVIDER_READY";
625
+ ProviderEvents2["Error"] = "PROVIDER_ERROR";
626
+ ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
627
+ ProviderEvents2["Stale"] = "PROVIDER_STALE";
628
+ return ProviderEvents2;
629
+ })(ProviderEvents || {});
630
+ var OpenFeatureEventEmitter = class {
631
+ constructor(globalLogger) {
632
+ this.globalLogger = globalLogger;
633
+ this._handlers = /* @__PURE__ */ new WeakMap();
634
+ this.eventEmitter = new import_events.default({ captureRejections: true });
635
+ this.eventEmitter.on("error", (err) => {
636
+ var _a;
637
+ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
638
+ });
639
+ }
640
+ emit(eventType, context) {
641
+ this.eventEmitter.emit(eventType, context);
642
+ }
643
+ addHandler(eventType, handler) {
644
+ const asyncHandler = (context) => __async(this, null, function* () {
645
+ yield handler(context);
646
+ });
647
+ this._handlers.set(handler, asyncHandler);
648
+ this.eventEmitter.on(eventType, asyncHandler);
649
+ }
650
+ removeHandler(eventType, handler) {
651
+ const asyncHandler = this._handlers.get(handler);
652
+ if (!asyncHandler) {
653
+ return;
654
+ }
655
+ this.eventEmitter.removeListener(eventType, asyncHandler);
656
+ }
657
+ removeAllHandlers(eventType) {
658
+ if (eventType) {
659
+ this.eventEmitter.removeAllListeners(eventType);
660
+ } else {
661
+ this.eventEmitter.removeAllListeners();
662
+ }
663
+ }
664
+ getHandlers(eventType) {
665
+ return this.eventEmitter.listeners(eventType);
666
+ }
667
+ setLogger(logger) {
668
+ this._eventLogger = new SafeLogger(logger);
669
+ return this;
670
+ }
671
+ get _logger() {
672
+ var _a;
673
+ return this._eventLogger || ((_a = this.globalLogger) == null ? void 0 : _a.call(this));
674
+ }
675
+ };
676
+
677
+ // ../shared/src/type-guards.ts
678
+ function isString(value) {
679
+ return typeof value === "string";
680
+ }
681
+ function stringOrUndefined(value) {
682
+ return isString(value) ? value : void 0;
683
+ }
684
+ function isObject(value) {
685
+ return typeof value === "object";
686
+ }
687
+ function objectOrUndefined(value) {
688
+ return isObject(value) ? value : void 0;
689
+ }
690
+
615
691
  // ../shared/src/open-feature.ts
616
692
  var OpenFeatureCommonAPI = class {
617
693
  constructor() {
618
694
  this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
619
695
  this._context = {};
620
696
  this._logger = new DefaultLogger();
697
+ this._events = new OpenFeatureEventEmitter(() => this._logger);
698
+ this._clientProviders = /* @__PURE__ */ new Map();
699
+ this._clientEvents = /* @__PURE__ */ new Map();
700
+ }
701
+ setLogger(logger) {
702
+ this._logger = new SafeLogger(logger);
703
+ return this;
704
+ }
705
+ /**
706
+ * Get metadata about registered provider.
707
+ * @returns {ProviderMetadata} Provider Metadata
708
+ */
709
+ get providerMetadata() {
710
+ return this._defaultProvider.metadata;
621
711
  }
622
712
  getContext() {
623
713
  return this._context;
624
714
  }
715
+ /**
716
+ * Adds a handler for the given provider event type.
717
+ * The handlers are called in the order they have been added.
718
+ * When changing the provider, the currently attached handlers will listen to the events of the new provider.
719
+ * @param {ProviderEvents} eventType The provider event type to listen to
720
+ * @param {EventHandler} handler The handler to run on occurrence of the event type
721
+ */
722
+ addHandler(eventType, handler) {
723
+ this._events.addHandler(eventType, handler);
724
+ }
725
+ /**
726
+ * Removes a handler for the given provider event type.
727
+ * @param {ProviderEvents} eventType The provider event type to remove the listener for
728
+ * @param {EventHandler} handler The handler to remove for the provider event type
729
+ */
730
+ removeHandler(eventType, handler) {
731
+ this._events.removeHandler(eventType, handler);
732
+ }
733
+ /**
734
+ * Gets the current handlers for the given provider event type.
735
+ * @param {ProviderEvents} eventType The provider event type to get the current handlers for
736
+ * @returns {EventHandler[]} The handlers currently attached to the given provider event type
737
+ */
738
+ getHandlers(eventType) {
739
+ return this._events.getHandlers(eventType);
740
+ }
741
+ setProvider(clientOrProvider, providerOrUndefined) {
742
+ var _a, _b, _c, _d, _e, _f;
743
+ const clientName = stringOrUndefined(clientOrProvider);
744
+ const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined);
745
+ if (!provider) {
746
+ return this;
747
+ }
748
+ const oldProvider = this.getProviderForClient(clientName);
749
+ if (oldProvider === provider) {
750
+ return this;
751
+ }
752
+ const clientEmitter = this.getEventEmitterForClient(clientName);
753
+ if (typeof provider.initialize === "function") {
754
+ (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => {
755
+ var _a2;
756
+ clientEmitter.emit("PROVIDER_READY" /* Ready */, { clientName });
757
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName });
758
+ })) == null ? void 0 : _d.catch((error) => {
759
+ var _a2;
760
+ clientEmitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
761
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
762
+ });
763
+ } else {
764
+ clientEmitter.emit("PROVIDER_READY" /* Ready */, { clientName });
765
+ (_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName });
766
+ }
767
+ if (clientName) {
768
+ this._clientProviders.set(clientName, provider);
769
+ } else {
770
+ this._defaultProvider = provider;
771
+ }
772
+ this.transferListeners(oldProvider, provider, clientName, clientEmitter);
773
+ if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) {
774
+ (_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider);
775
+ }
776
+ return this;
777
+ }
778
+ getProviderForClient(name) {
779
+ var _a;
780
+ if (!name) {
781
+ return this._defaultProvider;
782
+ }
783
+ return (_a = this._clientProviders.get(name)) != null ? _a : this._defaultProvider;
784
+ }
785
+ getEventEmitterForClient(name) {
786
+ const emitter = this._clientEvents.get(name);
787
+ if (emitter) {
788
+ return emitter;
789
+ }
790
+ const newEmitter = new OpenFeatureEventEmitter(() => this._logger);
791
+ this._clientEvents.set(name, newEmitter);
792
+ return newEmitter;
793
+ }
794
+ transferListeners(oldProvider, newProvider, clientName, clientEmitter) {
795
+ var _a;
796
+ (_a = oldProvider.events) == null ? void 0 : _a.removeAllHandlers();
797
+ Object.values(ProviderEvents).forEach(
798
+ (eventType) => {
799
+ var _a2;
800
+ return (_a2 = newProvider.events) == null ? void 0 : _a2.addHandler(eventType, (details) => __async(this, null, function* () {
801
+ clientEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
802
+ this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
803
+ }));
804
+ }
805
+ );
806
+ }
807
+ close() {
808
+ return __async(this, null, function* () {
809
+ var _a, _b;
810
+ try {
811
+ yield (_b = (_a = this == null ? void 0 : this._defaultProvider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a);
812
+ } catch (err) {
813
+ this.handleShutdownError(this._defaultProvider, err);
814
+ }
815
+ const providers = Array.from(this._clientProviders);
816
+ yield Promise.all(
817
+ providers.map((_0) => __async(this, [_0], function* ([, provider]) {
818
+ var _a2;
819
+ try {
820
+ yield (_a2 = provider.onClose) == null ? void 0 : _a2.call(provider);
821
+ } catch (err) {
822
+ this.handleShutdownError(this._defaultProvider, err);
823
+ }
824
+ }))
825
+ );
826
+ });
827
+ }
828
+ handleShutdownError(provider, err) {
829
+ this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`);
830
+ this._logger.error(err == null ? void 0 : err.stack);
831
+ }
625
832
  setTransactionContextPropagator(transactionContextPropagator) {
626
833
  const baseMessage = "Invalid TransactionContextPropagator, will not be set: ";
627
834
  if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.getTransactionContext) !== "function") {
@@ -656,6 +863,9 @@ var NoopFeatureProvider = class {
656
863
  name: "No-op Provider"
657
864
  };
658
865
  }
866
+ get status() {
867
+ return "NOT_READY" /* NOT_READY */;
868
+ }
659
869
  resolveBooleanEvaluation(_, defaultValue) {
660
870
  return this.noOp(defaultValue);
661
871
  }
@@ -677,35 +887,18 @@ var NoopFeatureProvider = class {
677
887
  };
678
888
  var NOOP_PROVIDER = new NoopFeatureProvider();
679
889
 
680
- // src/types.ts
681
- var import_events = __toESM(require_events());
682
- var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
683
- ProviderEvents2["Ready"] = "PROVIDER_READY";
684
- ProviderEvents2["Error"] = "PROVIDER_ERROR";
685
- ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
686
- ProviderEvents2["Stale"] = "PROVIDER_STALE";
687
- return ProviderEvents2;
688
- })(ProviderEvents || {});
689
- var ApiEvents = /* @__PURE__ */ ((ApiEvents2) => {
690
- ApiEvents2["ProviderChanged"] = "providerChanged";
691
- return ApiEvents2;
692
- })(ApiEvents || {});
693
-
694
890
  // src/open-feature.ts
695
- var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js.api");
891
+ var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/web-sdk/api");
696
892
  var _globalThis = globalThis;
697
893
  var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
698
894
  // eslint-disable-next-line @typescript-eslint/no-empty-function
699
895
  constructor() {
700
896
  super();
701
- this._apiEvents = new import_events.EventEmitter();
702
- this._providerReady = false;
703
897
  this._hooks = [];
704
- this._provider = NOOP_PROVIDER;
898
+ this._defaultProvider = NOOP_PROVIDER;
705
899
  }
706
900
  /**
707
901
  * Gets a singleton instance of the OpenFeature API.
708
- *
709
902
  * @ignore
710
903
  * @returns {OpenFeatureAPI} OpenFeature API
711
904
  */
@@ -718,14 +911,6 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
718
911
  _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
719
912
  return instance;
720
913
  }
721
- /**
722
- * Get metadata about registered provider.
723
- *
724
- * @returns {ProviderMetadata} Provider Metadata
725
- */
726
- get providerMetadata() {
727
- return this._provider.metadata;
728
- }
729
914
  setLogger(logger) {
730
915
  this._logger = new SafeLogger(logger);
731
916
  return this;
@@ -746,49 +931,26 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
746
931
  var _a, _b;
747
932
  const oldContext = this._context;
748
933
  this._context = context;
749
- yield (_b = (_a = this._provider) == null ? void 0 : _a.onContextChange) == null ? void 0 : _b.call(_a, oldContext, context);
750
- });
751
- }
752
- setProvider(provider) {
753
- var _a, _b, _c, _d, _e, _f, _g;
754
- if (this._provider !== provider) {
755
- const oldProvider = this._provider;
756
- this._provider = provider;
757
- this._providerReady = false;
758
- if (!this._provider.events) {
759
- this._provider.events = new import_events.EventEmitter();
760
- }
761
- if (typeof ((_a = this._provider) == null ? void 0 : _a.initialize) === "function") {
762
- (_e = (_d = (_c = (_b = this._provider).initialize) == null ? void 0 : _c.call(_b, this._context)) == null ? void 0 : _d.then(() => {
763
- var _a2;
764
- this._providerReady = true;
765
- (_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */);
766
- })) == null ? void 0 : _e.catch(() => {
767
- var _a2;
768
- (_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */);
769
- });
770
- } else {
771
- this._providerReady = true;
772
- (_f = this._provider.events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */);
773
- }
774
- this._apiEvents.emit("providerChanged" /* ProviderChanged */);
775
- (_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider);
776
- }
777
- return this;
778
- }
779
- close() {
780
- return __async(this, null, function* () {
781
- var _a, _b;
782
- yield (_b = (_a = this == null ? void 0 : this._provider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a);
934
+ yield (_b = (_a = this._defaultProvider) == null ? void 0 : _a.onContextChange) == null ? void 0 : _b.call(_a, oldContext, context);
783
935
  });
784
936
  }
937
+ /**
938
+ * A factory function for creating new named OpenFeature clients. Clients can contain
939
+ * their own state (e.g. logger, hook, context). Multiple clients can be used
940
+ * to segment feature flag configuration.
941
+ *
942
+ * If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.
943
+ * Otherwise, the default provider is used until a provider is assigned to that name.
944
+ * @param {string} name The name of the client
945
+ * @param {string} version The version of the client (only used for metadata)
946
+ * @returns {Client} OpenFeature Client
947
+ */
785
948
  getClient(name, version) {
786
949
  return new OpenFeatureClient(
787
950
  // functions are passed here to make sure that these values are always up to date,
788
951
  // and so we don't have to make these public properties on the API class.
789
- () => this._provider,
790
- () => this._providerReady,
791
- () => this._apiEvents,
952
+ () => this.getProviderForClient(name),
953
+ () => this.getEventEmitterForClient(name),
792
954
  () => this._logger,
793
955
  { name, version }
794
956
  );
@@ -798,27 +960,33 @@ var OpenFeature = OpenFeatureAPI.getInstance();
798
960
 
799
961
  // src/client.ts
800
962
  var OpenFeatureClient = class {
801
- constructor(providerAccessor, providerReady, apiEvents, globalLogger, options) {
963
+ constructor(providerAccessor, events, globalLogger, options) {
802
964
  this.providerAccessor = providerAccessor;
803
- this.providerReady = providerReady;
965
+ this.events = events;
804
966
  this.globalLogger = globalLogger;
967
+ this.options = options;
805
968
  this._hooks = [];
806
- this._handlerWrappers = [];
807
- this.metadata = {
808
- name: options.name,
809
- version: options.version
969
+ }
970
+ get metadata() {
971
+ return {
972
+ name: this.options.name,
973
+ version: this.options.version,
974
+ providerMetadata: this.providerAccessor().metadata
810
975
  };
811
- this.attachListeners();
812
- apiEvents().on("providerChanged" /* ProviderChanged */, () => {
813
- this.attachListeners();
814
- });
815
976
  }
816
977
  addHandler(eventType, handler) {
817
- this._handlerWrappers.push({ eventType, handler });
818
- if (eventType === "PROVIDER_READY" /* Ready */ && this.providerReady()) {
819
- handler();
978
+ this.events().addHandler(eventType, handler);
979
+ const providerReady = !this._provider.status || this._provider.status === "READY" /* READY */;
980
+ if (eventType === "PROVIDER_READY" /* Ready */ && providerReady) {
981
+ handler({ clientName: this.metadata.name });
820
982
  }
821
983
  }
984
+ removeHandler(notificationType, handler) {
985
+ this.events().removeHandler(notificationType, handler);
986
+ }
987
+ getHandlers(eventType) {
988
+ return this.events().getHandlers(eventType);
989
+ }
822
990
  setLogger(logger) {
823
991
  this._clientLogger = new SafeLogger(logger);
824
992
  return this;
@@ -838,13 +1006,7 @@ var OpenFeatureClient = class {
838
1006
  return this.getBooleanDetails(flagKey, defaultValue, options).value;
839
1007
  }
840
1008
  getBooleanDetails(flagKey, defaultValue, options) {
841
- return this.evaluate(
842
- flagKey,
843
- this._provider.resolveBooleanEvaluation,
844
- defaultValue,
845
- "boolean",
846
- options
847
- );
1009
+ return this.evaluate(flagKey, this._provider.resolveBooleanEvaluation, defaultValue, "boolean", options);
848
1010
  }
849
1011
  getStringValue(flagKey, defaultValue, options) {
850
1012
  return this.getStringDetails(flagKey, defaultValue, options).value;
@@ -879,6 +1041,7 @@ var OpenFeatureClient = class {
879
1041
  return this.evaluate(flagKey, this._provider.resolveObjectEvaluation, defaultValue, "object", options);
880
1042
  }
881
1043
  evaluate(flagKey, resolver, defaultValue, flagType, options = {}) {
1044
+ var _a;
882
1045
  const allHooks = [
883
1046
  ...OpenFeature.getHooks(),
884
1047
  ...this.getHooks(),
@@ -900,6 +1063,7 @@ var OpenFeatureClient = class {
900
1063
  this.beforeHooks(allHooks, hookContext, options);
901
1064
  const resolution = resolver.call(this._provider, flagKey, defaultValue, context, this._logger);
902
1065
  const evaluationDetails = __spreadProps(__spreadValues({}, resolution), {
1066
+ flagMetadata: Object.freeze((_a = resolution.flagMetadata) != null ? _a : {}),
903
1067
  flagKey
904
1068
  });
905
1069
  this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
@@ -913,6 +1077,7 @@ var OpenFeatureClient = class {
913
1077
  errorMessage,
914
1078
  value: defaultValue,
915
1079
  reason: StandardResolutionReasons.ERROR,
1080
+ flagMetadata: Object.freeze({}),
916
1081
  flagKey
917
1082
  };
918
1083
  } finally {
@@ -967,18 +1132,8 @@ var OpenFeatureClient = class {
967
1132
  get _logger() {
968
1133
  return this._clientLogger || this.globalLogger();
969
1134
  }
970
- attachListeners() {
971
- Object.values(ProviderEvents).forEach((eventType) => {
972
- var _a;
973
- return (_a = this._provider.events) == null ? void 0 : _a.on(eventType, () => {
974
- this._handlerWrappers.filter((wrapper) => wrapper.eventType === eventType).forEach((wrapper) => wrapper.handler());
975
- });
976
- });
977
- }
978
1135
  };
979
- var export_OpenFeatureEventEmitter = import_events.EventEmitter;
980
1136
  export {
981
- ApiEvents,
982
1137
  DefaultLogger,
983
1138
  ErrorCode,
984
1139
  FlagNotFoundError,
@@ -991,9 +1146,10 @@ export {
991
1146
  OpenFeatureClient,
992
1147
  OpenFeatureCommonAPI,
993
1148
  OpenFeatureError,
994
- export_OpenFeatureEventEmitter as OpenFeatureEventEmitter,
1149
+ OpenFeatureEventEmitter,
995
1150
  ParseError,
996
1151
  ProviderEvents,
1152
+ ProviderStatus,
997
1153
  SafeLogger,
998
1154
  StandardResolutionReasons,
999
1155
  TargetingKeyMissingError,