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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -446,7 +446,9 @@ __export(src_exports, {
446
446
  ErrorCode: () => ErrorCode,
447
447
  FlagNotFoundError: () => FlagNotFoundError,
448
448
  GeneralError: () => GeneralError,
449
+ InternalEventEmitter: () => InternalEventEmitter,
449
450
  InvalidContextError: () => InvalidContextError,
451
+ LOG_LEVELS: () => LOG_LEVELS,
450
452
  NOOP_PROVIDER: () => NOOP_PROVIDER,
451
453
  NOOP_TRANSACTION_CONTEXT_PROPAGATOR: () => NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
452
454
  OpenFeature: () => OpenFeature,
@@ -461,11 +463,24 @@ __export(src_exports, {
461
463
  SafeLogger: () => SafeLogger,
462
464
  StandardResolutionReasons: () => StandardResolutionReasons,
463
465
  TargetingKeyMissingError: () => TargetingKeyMissingError,
464
- TypeMismatchError: () => TypeMismatchError
466
+ TypeMismatchError: () => TypeMismatchError,
467
+ isObject: () => isObject,
468
+ isString: () => isString,
469
+ objectOrUndefined: () => objectOrUndefined,
470
+ stringOrUndefined: () => stringOrUndefined
465
471
  });
466
472
  module.exports = __toCommonJS(src_exports);
467
473
 
468
- // ../shared/src/types.ts
474
+ // ../shared/src/errors/open-feature-error-abstract.ts
475
+ var OpenFeatureError = class extends Error {
476
+ constructor(message) {
477
+ super(message);
478
+ Object.setPrototypeOf(this, OpenFeatureError.prototype);
479
+ this.name = "OpenFeatureError";
480
+ }
481
+ };
482
+
483
+ // ../shared/src/evaluation/evaluation.ts
469
484
  var StandardResolutionReasons = {
470
485
  /**
471
486
  * The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.
@@ -512,21 +527,6 @@ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
512
527
  ErrorCode2["GENERAL"] = "GENERAL";
513
528
  return ErrorCode2;
514
529
  })(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 || {});
521
-
522
- // ../shared/src/errors/open-feature-error-abstract.ts
523
- var OpenFeatureError = class extends Error {
524
- constructor(message) {
525
- super(message);
526
- Object.setPrototypeOf(this, OpenFeatureError.prototype);
527
- this.name = "OpenFeatureError";
528
- }
529
- };
530
530
 
531
531
  // ../shared/src/errors/general-error.ts
532
532
  var GeneralError = class extends OpenFeatureError {
@@ -588,8 +588,16 @@ var InvalidContextError = class extends OpenFeatureError {
588
588
  }
589
589
  };
590
590
 
591
- // ../shared/src/logger.ts
592
- var LOG_LEVELS = ["error", "warn", "info", "debug"];
591
+ // ../shared/src/events/events.ts
592
+ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
593
+ ProviderEvents2["Ready"] = "PROVIDER_READY";
594
+ ProviderEvents2["Error"] = "PROVIDER_ERROR";
595
+ ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
596
+ ProviderEvents2["Stale"] = "PROVIDER_STALE";
597
+ return ProviderEvents2;
598
+ })(ProviderEvents || {});
599
+
600
+ // ../shared/src/logger/default-logger.ts
593
601
  var DefaultLogger = class {
594
602
  error(...args) {
595
603
  console.error(...args);
@@ -602,6 +610,9 @@ var DefaultLogger = class {
602
610
  debug() {
603
611
  }
604
612
  };
613
+
614
+ // ../shared/src/logger/safe-logger.ts
615
+ var LOG_LEVELS = ["error", "warn", "info", "debug"];
605
616
  var SafeLogger = class {
606
617
  constructor(logger) {
607
618
  this.fallbackLogger = new DefaultLogger();
@@ -639,29 +650,12 @@ var SafeLogger = class {
639
650
  }
640
651
  };
641
652
 
642
- // ../shared/src/no-op-transaction-context-propagator.ts
643
- var NoopTransactionContextPropagator = class {
644
- getTransactionContext() {
645
- return {};
646
- }
647
- setTransactionContext(_, callback) {
648
- callback();
649
- }
650
- };
651
- var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
652
-
653
- // ../shared/src/events.ts
653
+ // ../shared/src/events/open-feature-event-emitter.ts
654
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 {
655
+ var GenericEventEmitter = class {
663
656
  constructor(globalLogger) {
664
657
  this.globalLogger = globalLogger;
658
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
665
659
  this._handlers = /* @__PURE__ */ new WeakMap();
666
660
  this.eventEmitter = new import_events.default({ captureRejections: true });
667
661
  this.eventEmitter.on("error", (err) => {
@@ -701,10 +695,33 @@ var OpenFeatureEventEmitter = class {
701
695
  return this;
702
696
  }
703
697
  get _logger() {
704
- var _a;
705
- return this._eventLogger || ((_a = this.globalLogger) == null ? void 0 : _a.call(this));
698
+ var _a, _b;
699
+ return (_b = this._eventLogger) != null ? _b : (_a = this.globalLogger) == null ? void 0 : _a.call(this);
700
+ }
701
+ };
702
+ var OpenFeatureEventEmitter = class extends GenericEventEmitter {
703
+ };
704
+ var InternalEventEmitter = class extends GenericEventEmitter {
705
+ };
706
+
707
+ // ../shared/src/provider/provider.ts
708
+ var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
709
+ ProviderStatus2["NOT_READY"] = "NOT_READY";
710
+ ProviderStatus2["READY"] = "READY";
711
+ ProviderStatus2["ERROR"] = "ERROR";
712
+ return ProviderStatus2;
713
+ })(ProviderStatus || {});
714
+
715
+ // ../shared/src/transaction-context/no-op-transaction-context-propagator.ts
716
+ var NoopTransactionContextPropagator = class {
717
+ getTransactionContext() {
718
+ return {};
719
+ }
720
+ setTransactionContext(_, callback) {
721
+ callback();
706
722
  }
707
723
  };
724
+ var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
708
725
 
709
726
  // ../shared/src/type-guards.ts
710
727
  function isString(value) {
@@ -728,14 +745,26 @@ function isDefined(input) {
728
745
  // ../shared/src/open-feature.ts
729
746
  var OpenFeatureCommonAPI = class {
730
747
  constructor() {
748
+ this._hooks = [];
731
749
  this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
732
750
  this._context = {};
733
751
  this._logger = new DefaultLogger();
734
- this._events = new OpenFeatureEventEmitter(() => this._logger);
752
+ this._events = new InternalEventEmitter(() => this._logger);
735
753
  this._clientEventHandlers = /* @__PURE__ */ new Map();
736
754
  this._clientProviders = /* @__PURE__ */ new Map();
737
755
  this._clientEvents = /* @__PURE__ */ new Map();
738
756
  }
757
+ addHooks(...hooks) {
758
+ this._hooks = [...this._hooks, ...hooks];
759
+ return this;
760
+ }
761
+ getHooks() {
762
+ return this._hooks;
763
+ }
764
+ clearHooks() {
765
+ this._hooks = [];
766
+ return this;
767
+ }
739
768
  setLogger(logger) {
740
769
  this._logger = new SafeLogger(logger);
741
770
  return this;
@@ -747,9 +776,6 @@ var OpenFeatureCommonAPI = class {
747
776
  get providerMetadata() {
748
777
  return this._defaultProvider.metadata;
749
778
  }
750
- getContext() {
751
- return this._context;
752
- }
753
779
  /**
754
780
  * Adds a handler for the given provider event type.
755
781
  * The handlers are called in the order they have been added.
@@ -787,17 +813,17 @@ var OpenFeatureCommonAPI = class {
787
813
  if (oldProvider === provider) {
788
814
  return this;
789
815
  }
790
- const emitters = clientName ? [this.getAndCacheEventEmitterForClient(clientName)] : this.getUnboundEmitters();
816
+ const emitters = this.getAssociatedEventEmitters(clientName);
791
817
  if (typeof provider.initialize === "function") {
792
818
  (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => {
793
819
  var _a2;
794
- emitters.forEach((emitter) => {
820
+ this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
795
821
  emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName });
796
822
  });
797
823
  (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName });
798
824
  })) == null ? void 0 : _d.catch((error) => {
799
825
  var _a2;
800
- emitters.forEach((emitter) => {
826
+ this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
801
827
  emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
802
828
  });
803
829
  (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
@@ -826,12 +852,12 @@ var OpenFeatureCommonAPI = class {
826
852
  }
827
853
  return (_a = this._clientProviders.get(name)) != null ? _a : this._defaultProvider;
828
854
  }
829
- getAndCacheEventEmitterForClient(name) {
855
+ buildAndCacheEventEmitterForClient(name) {
830
856
  const emitter = this._clientEvents.get(name);
831
857
  if (emitter) {
832
858
  return emitter;
833
859
  }
834
- const newEmitter = new OpenFeatureEventEmitter(() => this._logger);
860
+ const newEmitter = new InternalEventEmitter(() => this._logger);
835
861
  this._clientEvents.set(name, newEmitter);
836
862
  const clientProvider = this.getProviderForClient(name);
837
863
  Object.values(ProviderEvents).forEach(
@@ -848,7 +874,15 @@ var OpenFeatureCommonAPI = class {
848
874
  const namedProviders = [...this._clientProviders.keys()];
849
875
  const eventEmitterNames = [...this._clientEvents.keys()].filter(isDefined);
850
876
  const unboundEmitterNames = eventEmitterNames.filter((name) => !namedProviders.includes(name));
851
- return unboundEmitterNames.map((name) => this._clientEvents.get(name)).filter(isDefined);
877
+ return [
878
+ // all unbound, named emitters
879
+ ...unboundEmitterNames.map((name) => this._clientEvents.get(name)),
880
+ // the default emitter
881
+ this._clientEvents.get(void 0)
882
+ ].filter(isDefined);
883
+ }
884
+ getAssociatedEventEmitters(clientName) {
885
+ return clientName ? [this.buildAndCacheEventEmitterForClient(clientName)] : this.getUnboundEmitters();
852
886
  }
853
887
  transferListeners(oldProvider, newProvider, clientName, emitters) {
854
888
  var _a;
@@ -856,17 +890,15 @@ var OpenFeatureCommonAPI = class {
856
890
  var _a2;
857
891
  return (_a2 = oldProvider.events) == null ? void 0 : _a2.removeHandler(...eventHandler);
858
892
  });
859
- const newClientHandlers = Object.values(ProviderEvents).map(
860
- (eventType) => {
861
- const handler = (details) => __async(this, null, function* () {
862
- emitters.forEach((emitter) => {
863
- emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
864
- });
865
- this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
893
+ const newClientHandlers = Object.values(ProviderEvents).map((eventType) => {
894
+ const handler = (details) => __async(this, null, function* () {
895
+ emitters.forEach((emitter) => {
896
+ emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
866
897
  });
867
- return [eventType, handler];
868
- }
869
- );
898
+ this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
899
+ });
900
+ return [eventType, handler];
901
+ });
870
902
  this._clientEventHandlers.set(clientName, newClientHandlers);
871
903
  newClientHandlers.forEach((eventHandler) => {
872
904
  var _a2;
@@ -924,7 +956,7 @@ var OpenFeatureCommonAPI = class {
924
956
  }
925
957
  };
926
958
 
927
- // src/no-op-provider.ts
959
+ // src/provider/no-op-provider.ts
928
960
  var REASON_NO_OP = "No-op";
929
961
  var NoopFeatureProvider = class {
930
962
  constructor() {
@@ -963,7 +995,6 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
963
995
  // eslint-disable-next-line @typescript-eslint/no-empty-function
964
996
  constructor() {
965
997
  super();
966
- this._hooks = [];
967
998
  this._defaultProvider = NOOP_PROVIDER;
968
999
  }
969
1000
  /**
@@ -980,29 +1011,26 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
980
1011
  _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
981
1012
  return instance;
982
1013
  }
983
- setLogger(logger) {
984
- this._logger = new SafeLogger(logger);
985
- return this;
986
- }
987
- addHooks(...hooks) {
988
- this._hooks = [...this._hooks, ...hooks];
989
- return this;
990
- }
991
- getHooks() {
992
- return this._hooks;
993
- }
994
- clearHooks() {
995
- this._hooks = [];
996
- return this;
997
- }
998
1014
  setContext(context) {
999
1015
  return __async(this, null, function* () {
1000
- var _a, _b;
1001
1016
  const oldContext = this._context;
1002
1017
  this._context = context;
1003
- yield (_b = (_a = this._defaultProvider) == null ? void 0 : _a.onContextChange) == null ? void 0 : _b.call(_a, oldContext, context);
1018
+ const allProviders = [this._defaultProvider, ...this._clientProviders.values()];
1019
+ yield Promise.all(
1020
+ allProviders.map((provider) => __async(this, null, function* () {
1021
+ var _a, _b;
1022
+ try {
1023
+ return yield (_a = provider.onContextChange) == null ? void 0 : _a.call(provider, oldContext, context);
1024
+ } catch (err) {
1025
+ (_b = this._logger) == null ? void 0 : _b.error(`Error running context change handler of provider ${provider.metadata.name}:`, err);
1026
+ }
1027
+ }))
1028
+ );
1004
1029
  });
1005
1030
  }
1031
+ getContext() {
1032
+ return this._context;
1033
+ }
1006
1034
  /**
1007
1035
  * A factory function for creating new named OpenFeature clients. Clients can contain
1008
1036
  * their own state (e.g. logger, hook, context). Multiple clients can be used
@@ -1019,7 +1047,7 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
1019
1047
  // functions are passed here to make sure that these values are always up to date,
1020
1048
  // and so we don't have to make these public properties on the API class.
1021
1049
  () => this.getProviderForClient(name),
1022
- () => this.getAndCacheEventEmitterForClient(name),
1050
+ () => this.buildAndCacheEventEmitterForClient(name),
1023
1051
  () => this._logger,
1024
1052
  { name, version }
1025
1053
  );
@@ -1027,7 +1055,7 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
1027
1055
  };
1028
1056
  var OpenFeature = OpenFeatureAPI.getInstance();
1029
1057
 
1030
- // src/client.ts
1058
+ // src/client/open-feature-client.ts
1031
1059
  var OpenFeatureClient = class {
1032
1060
  constructor(providerAccessor, emitterAccessor, globalLogger, options) {
1033
1061
  this.providerAccessor = providerAccessor;