@openfeature/web-sdk 0.3.11 → 0.4.1

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
@@ -550,6 +550,15 @@ var InvalidContextError = class extends OpenFeatureError {
550
550
  }
551
551
  };
552
552
 
553
+ // ../shared/src/provider/provider.ts
554
+ var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
555
+ ProviderStatus2["NOT_READY"] = "NOT_READY";
556
+ ProviderStatus2["READY"] = "READY";
557
+ ProviderStatus2["ERROR"] = "ERROR";
558
+ ProviderStatus2["STALE"] = "STALE";
559
+ return ProviderStatus2;
560
+ })(ProviderStatus || {});
561
+
553
562
  // ../shared/src/events/events.ts
554
563
  var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
555
564
  ProviderEvents2["Ready"] = "PROVIDER_READY";
@@ -559,6 +568,20 @@ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
559
568
  return ProviderEvents2;
560
569
  })(ProviderEvents || {});
561
570
 
571
+ // ../shared/src/events/event-utils.ts
572
+ var eventStatusMap = {
573
+ ["READY" /* READY */]: "PROVIDER_READY" /* Ready */,
574
+ ["ERROR" /* ERROR */]: "PROVIDER_ERROR" /* Error */,
575
+ ["STALE" /* STALE */]: "PROVIDER_STALE" /* Stale */,
576
+ ["NOT_READY" /* NOT_READY */]: void 0
577
+ };
578
+ var statusMatchesEvent = (event, status) => {
579
+ return !status && event === "PROVIDER_READY" /* Ready */ || eventStatusMap[status] === event;
580
+ };
581
+
582
+ // ../shared/src/events/open-feature-event-emitter.ts
583
+ var import_events2 = __toESM(require_events());
584
+
562
585
  // ../shared/src/logger/default-logger.ts
563
586
  var DefaultLogger = class {
564
587
  error(...args) {
@@ -613,13 +636,12 @@ var SafeLogger = class {
613
636
  };
614
637
 
615
638
  // ../shared/src/events/open-feature-event-emitter.ts
616
- var import_events = __toESM(require_events());
617
639
  var GenericEventEmitter = class {
618
640
  constructor(globalLogger) {
619
641
  this.globalLogger = globalLogger;
620
642
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
621
643
  this._handlers = /* @__PURE__ */ new WeakMap();
622
- this.eventEmitter = new import_events.default({ captureRejections: true });
644
+ this.eventEmitter = new import_events2.default({ captureRejections: true });
623
645
  this.eventEmitter.on("error", (err) => {
624
646
  var _a;
625
647
  (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
@@ -629,8 +651,8 @@ var GenericEventEmitter = class {
629
651
  this.eventEmitter.emit(eventType, context);
630
652
  }
631
653
  addHandler(eventType, handler) {
632
- const asyncHandler = (context) => __async(this, null, function* () {
633
- yield handler(context);
654
+ const asyncHandler = (details) => __async(this, null, function* () {
655
+ yield handler(details);
634
656
  });
635
657
  this._handlers.set(handler, asyncHandler);
636
658
  this.eventEmitter.on(eventType, asyncHandler);
@@ -666,14 +688,6 @@ var OpenFeatureEventEmitter = class extends GenericEventEmitter {
666
688
  var InternalEventEmitter = class extends GenericEventEmitter {
667
689
  };
668
690
 
669
- // ../shared/src/provider/provider.ts
670
- var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
671
- ProviderStatus2["NOT_READY"] = "NOT_READY";
672
- ProviderStatus2["READY"] = "READY";
673
- ProviderStatus2["ERROR"] = "ERROR";
674
- return ProviderStatus2;
675
- })(ProviderStatus || {});
676
-
677
691
  // ../shared/src/transaction-context/no-op-transaction-context-propagator.ts
678
692
  var NoopTransactionContextPropagator = class {
679
693
  getTransactionContext() {
@@ -706,7 +720,7 @@ function isDefined(input) {
706
720
 
707
721
  // ../shared/src/open-feature.ts
708
722
  var OpenFeatureCommonAPI = class {
709
- constructor() {
723
+ constructor(category) {
710
724
  this._hooks = [];
711
725
  this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
712
726
  this._context = {};
@@ -715,6 +729,7 @@ var OpenFeatureCommonAPI = class {
715
729
  this._clientEventHandlers = /* @__PURE__ */ new Map();
716
730
  this._clientProviders = /* @__PURE__ */ new Map();
717
731
  this._clientEvents = /* @__PURE__ */ new Map();
732
+ this._runsOn = category;
718
733
  }
719
734
  addHooks(...hooks) {
720
735
  this._hooks = [...this._hooks, ...hooks];
@@ -741,11 +756,24 @@ var OpenFeatureCommonAPI = class {
741
756
  /**
742
757
  * Adds a handler for the given provider event type.
743
758
  * The handlers are called in the order they have been added.
744
- * When changing the provider, the currently attached handlers will listen to the events of the new provider.
759
+ * API (global) events run for all providers.
745
760
  * @param {ProviderEvents} eventType The provider event type to listen to
746
761
  * @param {EventHandler} handler The handler to run on occurrence of the event type
747
762
  */
748
763
  addHandler(eventType, handler) {
764
+ [.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._clientProviders].forEach((keyProviderTuple) => {
765
+ var _a;
766
+ const clientName = keyProviderTuple[0];
767
+ const provider = keyProviderTuple[1];
768
+ const shouldRunNow = statusMatchesEvent(eventType, keyProviderTuple[1].status);
769
+ if (shouldRunNow) {
770
+ try {
771
+ handler({ clientName, providerName: provider.metadata.name });
772
+ } catch (err) {
773
+ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
774
+ }
775
+ }
776
+ });
749
777
  this._events.addHandler(eventType, handler);
750
778
  }
751
779
  /**
@@ -764,43 +792,66 @@ var OpenFeatureCommonAPI = class {
764
792
  getHandlers(eventType) {
765
793
  return this._events.getHandlers(eventType);
766
794
  }
795
+ setProviderAndWait(clientOrProvider, providerOrUndefined) {
796
+ return __async(this, null, function* () {
797
+ yield this.setAwaitableProvider(clientOrProvider, providerOrUndefined);
798
+ });
799
+ }
767
800
  setProvider(clientOrProvider, providerOrUndefined) {
768
- var _a, _b, _c, _d, _e, _f, _g;
801
+ const maybePromise = this.setAwaitableProvider(clientOrProvider, providerOrUndefined);
802
+ if (maybePromise) {
803
+ maybePromise.catch(() => {
804
+ });
805
+ }
806
+ return this;
807
+ }
808
+ setAwaitableProvider(clientOrProvider, providerOrUndefined) {
809
+ var _a, _b, _c, _d, _e, _f;
769
810
  const clientName = stringOrUndefined(clientOrProvider);
770
811
  const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined);
771
812
  if (!provider) {
772
- return this;
813
+ this._logger.debug("No provider defined, ignoring setProvider call");
814
+ return;
773
815
  }
774
816
  const oldProvider = this.getProviderForClient(clientName);
817
+ const providerName = provider.metadata.name;
775
818
  if (oldProvider === provider) {
776
- return this;
819
+ this._logger.debug("Provider is already set, ignoring setProvider call");
820
+ return;
821
+ }
822
+ if (!provider.runsOn) {
823
+ this._logger.debug(`Provider '${provider.metadata.name}' has not defined its intended use.`);
824
+ } else if (provider.runsOn !== this._runsOn) {
825
+ throw new GeneralError(`Provider '${provider.metadata.name}' is intended for use on the ${provider.runsOn}.`);
777
826
  }
778
827
  const emitters = this.getAssociatedEventEmitters(clientName);
779
828
  if (typeof provider.initialize === "function" && provider.status === void 0) {
780
829
  const activeLogger = this._logger || console;
781
830
  activeLogger.warn(
782
- `Provider ${(_b = provider == null ? void 0 : provider.metadata) == null ? void 0 : _b.name} implements 'initialize' but not 'status'. Please implement 'status'.`
831
+ `Provider ${providerName} implements 'initialize' but not 'status'. Please implement 'status'.`
783
832
  );
784
833
  }
834
+ let initializationPromise = void 0;
785
835
  if ((provider == null ? void 0 : provider.status) === "NOT_READY" /* NOT_READY */ && typeof provider.initialize === "function") {
786
- (_e = (_d = (_c = provider.initialize) == null ? void 0 : _c.call(provider, this._context)) == null ? void 0 : _d.then(() => {
836
+ initializationPromise = (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => {
787
837
  var _a2;
788
838
  this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
789
- emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName });
839
+ emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
790
840
  });
791
- (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName });
792
- })) == null ? void 0 : _e.catch((error) => {
841
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
842
+ })) == null ? void 0 : _d.catch((error) => {
793
843
  var _a2;
794
844
  this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
795
- emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
845
+ emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message });
796
846
  });
797
- (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
847
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message });
848
+ throw error;
798
849
  });
799
850
  } else {
800
851
  emitters.forEach((emitter) => {
801
- emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName });
852
+ emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
802
853
  });
803
- (_f = this._events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */, { clientName });
854
+ (_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
804
855
  }
805
856
  if (clientName) {
806
857
  this._clientProviders.set(clientName, provider);
@@ -809,9 +860,9 @@ var OpenFeatureCommonAPI = class {
809
860
  }
810
861
  this.transferListeners(oldProvider, provider, clientName, emitters);
811
862
  if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) {
812
- (_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider);
863
+ (_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider);
813
864
  }
814
- return this;
865
+ return initializationPromise;
815
866
  }
816
867
  getProviderForClient(name) {
817
868
  var _a;
@@ -832,7 +883,7 @@ var OpenFeatureCommonAPI = class {
832
883
  (eventType) => {
833
884
  var _a;
834
885
  return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () {
835
- newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name }));
886
+ newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name, providerName: clientProvider.metadata.name }));
836
887
  }));
837
888
  }
838
889
  );
@@ -861,9 +912,9 @@ var OpenFeatureCommonAPI = class {
861
912
  const newClientHandlers = Object.values(ProviderEvents).map((eventType) => {
862
913
  const handler = (details) => __async(this, null, function* () {
863
914
  emitters.forEach((emitter) => {
864
- emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
915
+ emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name }));
865
916
  });
866
- this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
917
+ this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name }));
867
918
  });
868
919
  return [eventType, handler];
869
920
  });
@@ -962,7 +1013,7 @@ var _globalThis = globalThis;
962
1013
  var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
963
1014
  // eslint-disable-next-line @typescript-eslint/no-empty-function
964
1015
  constructor() {
965
- super();
1016
+ super("client");
966
1017
  this._defaultProvider = NOOP_PROVIDER;
967
1018
  }
968
1019
  /**
@@ -1045,7 +1096,7 @@ var OpenFeatureClient = class {
1045
1096
  const providerReady = !this._provider.status || this._provider.status === "READY" /* READY */;
1046
1097
  if (eventType === "PROVIDER_READY" /* Ready */ && providerReady) {
1047
1098
  try {
1048
- handler({ clientName: this.metadata.name });
1099
+ handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });
1049
1100
  } catch (err) {
1050
1101
  (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
1051
1102
  }
@@ -1229,6 +1280,7 @@ export {
1229
1280
  isObject,
1230
1281
  isString,
1231
1282
  objectOrUndefined,
1283
+ statusMatchesEvent,
1232
1284
  stringOrUndefined
1233
1285
  };
1234
1286
  //# sourceMappingURL=index.js.map