@openfeature/web-sdk 0.4.0 → 0.4.2
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 +235 -138
- package/dist/cjs/index.js +105 -71
- package/dist/cjs/index.js.map +4 -4
- package/dist/esm/index.js +105 -71
- package/dist/esm/index.js.map +4 -4
- package/dist/types.d.ts +186 -188
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -450,7 +450,6 @@ __export(src_exports, {
|
|
|
450
450
|
InvalidContextError: () => InvalidContextError,
|
|
451
451
|
LOG_LEVELS: () => LOG_LEVELS,
|
|
452
452
|
NOOP_PROVIDER: () => NOOP_PROVIDER,
|
|
453
|
-
NOOP_TRANSACTION_CONTEXT_PROPAGATOR: () => NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
|
|
454
453
|
OpenFeature: () => OpenFeature,
|
|
455
454
|
OpenFeatureAPI: () => OpenFeatureAPI,
|
|
456
455
|
OpenFeatureClient: () => OpenFeatureClient,
|
|
@@ -467,6 +466,7 @@ __export(src_exports, {
|
|
|
467
466
|
isObject: () => isObject,
|
|
468
467
|
isString: () => isString,
|
|
469
468
|
objectOrUndefined: () => objectOrUndefined,
|
|
469
|
+
statusMatchesEvent: () => statusMatchesEvent,
|
|
470
470
|
stringOrUndefined: () => stringOrUndefined
|
|
471
471
|
});
|
|
472
472
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -588,6 +588,15 @@ var InvalidContextError = class extends OpenFeatureError {
|
|
|
588
588
|
}
|
|
589
589
|
};
|
|
590
590
|
|
|
591
|
+
// ../shared/src/provider/provider.ts
|
|
592
|
+
var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
|
|
593
|
+
ProviderStatus2["NOT_READY"] = "NOT_READY";
|
|
594
|
+
ProviderStatus2["READY"] = "READY";
|
|
595
|
+
ProviderStatus2["ERROR"] = "ERROR";
|
|
596
|
+
ProviderStatus2["STALE"] = "STALE";
|
|
597
|
+
return ProviderStatus2;
|
|
598
|
+
})(ProviderStatus || {});
|
|
599
|
+
|
|
591
600
|
// ../shared/src/events/events.ts
|
|
592
601
|
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
|
|
593
602
|
ProviderEvents2["Ready"] = "PROVIDER_READY";
|
|
@@ -597,6 +606,20 @@ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
|
|
|
597
606
|
return ProviderEvents2;
|
|
598
607
|
})(ProviderEvents || {});
|
|
599
608
|
|
|
609
|
+
// ../shared/src/events/event-utils.ts
|
|
610
|
+
var eventStatusMap = {
|
|
611
|
+
["READY" /* READY */]: "PROVIDER_READY" /* Ready */,
|
|
612
|
+
["ERROR" /* ERROR */]: "PROVIDER_ERROR" /* Error */,
|
|
613
|
+
["STALE" /* STALE */]: "PROVIDER_STALE" /* Stale */,
|
|
614
|
+
["NOT_READY" /* NOT_READY */]: void 0
|
|
615
|
+
};
|
|
616
|
+
var statusMatchesEvent = (event, status) => {
|
|
617
|
+
return !status && event === "PROVIDER_READY" /* Ready */ || eventStatusMap[status] === event;
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
// ../shared/src/events/open-feature-event-emitter.ts
|
|
621
|
+
var import_events2 = __toESM(require_events());
|
|
622
|
+
|
|
600
623
|
// ../shared/src/logger/default-logger.ts
|
|
601
624
|
var DefaultLogger = class {
|
|
602
625
|
error(...args) {
|
|
@@ -651,13 +674,12 @@ var SafeLogger = class {
|
|
|
651
674
|
};
|
|
652
675
|
|
|
653
676
|
// ../shared/src/events/open-feature-event-emitter.ts
|
|
654
|
-
var import_events = __toESM(require_events());
|
|
655
677
|
var GenericEventEmitter = class {
|
|
656
678
|
constructor(globalLogger) {
|
|
657
679
|
this.globalLogger = globalLogger;
|
|
658
680
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
659
681
|
this._handlers = /* @__PURE__ */ new WeakMap();
|
|
660
|
-
this.eventEmitter = new
|
|
682
|
+
this.eventEmitter = new import_events2.default({ captureRejections: true });
|
|
661
683
|
this.eventEmitter.on("error", (err) => {
|
|
662
684
|
var _a;
|
|
663
685
|
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
|
|
@@ -667,8 +689,8 @@ var GenericEventEmitter = class {
|
|
|
667
689
|
this.eventEmitter.emit(eventType, context);
|
|
668
690
|
}
|
|
669
691
|
addHandler(eventType, handler) {
|
|
670
|
-
const asyncHandler = (
|
|
671
|
-
yield handler(
|
|
692
|
+
const asyncHandler = (details) => __async(this, null, function* () {
|
|
693
|
+
yield handler(details);
|
|
672
694
|
});
|
|
673
695
|
this._handlers.set(handler, asyncHandler);
|
|
674
696
|
this.eventEmitter.on(eventType, asyncHandler);
|
|
@@ -704,25 +726,6 @@ var OpenFeatureEventEmitter = class extends GenericEventEmitter {
|
|
|
704
726
|
var InternalEventEmitter = class extends GenericEventEmitter {
|
|
705
727
|
};
|
|
706
728
|
|
|
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();
|
|
722
|
-
}
|
|
723
|
-
};
|
|
724
|
-
var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
|
|
725
|
-
|
|
726
729
|
// ../shared/src/type-guards.ts
|
|
727
730
|
function isString(value) {
|
|
728
731
|
return typeof value === "string";
|
|
@@ -744,15 +747,15 @@ function isDefined(input) {
|
|
|
744
747
|
|
|
745
748
|
// ../shared/src/open-feature.ts
|
|
746
749
|
var OpenFeatureCommonAPI = class {
|
|
747
|
-
constructor() {
|
|
750
|
+
constructor(category) {
|
|
748
751
|
this._hooks = [];
|
|
749
|
-
this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
|
|
750
752
|
this._context = {};
|
|
751
753
|
this._logger = new DefaultLogger();
|
|
752
754
|
this._events = new InternalEventEmitter(() => this._logger);
|
|
753
755
|
this._clientEventHandlers = /* @__PURE__ */ new Map();
|
|
754
756
|
this._clientProviders = /* @__PURE__ */ new Map();
|
|
755
757
|
this._clientEvents = /* @__PURE__ */ new Map();
|
|
758
|
+
this._runsOn = category;
|
|
756
759
|
}
|
|
757
760
|
addHooks(...hooks) {
|
|
758
761
|
this._hooks = [...this._hooks, ...hooks];
|
|
@@ -779,11 +782,24 @@ var OpenFeatureCommonAPI = class {
|
|
|
779
782
|
/**
|
|
780
783
|
* Adds a handler for the given provider event type.
|
|
781
784
|
* The handlers are called in the order they have been added.
|
|
782
|
-
*
|
|
785
|
+
* API (global) events run for all providers.
|
|
783
786
|
* @param {ProviderEvents} eventType The provider event type to listen to
|
|
784
787
|
* @param {EventHandler} handler The handler to run on occurrence of the event type
|
|
785
788
|
*/
|
|
786
789
|
addHandler(eventType, handler) {
|
|
790
|
+
[.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._clientProviders].forEach((keyProviderTuple) => {
|
|
791
|
+
var _a;
|
|
792
|
+
const clientName = keyProviderTuple[0];
|
|
793
|
+
const provider = keyProviderTuple[1];
|
|
794
|
+
const shouldRunNow = statusMatchesEvent(eventType, keyProviderTuple[1].status);
|
|
795
|
+
if (shouldRunNow) {
|
|
796
|
+
try {
|
|
797
|
+
handler({ clientName, providerName: provider.metadata.name });
|
|
798
|
+
} catch (err) {
|
|
799
|
+
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
});
|
|
787
803
|
this._events.addHandler(eventType, handler);
|
|
788
804
|
}
|
|
789
805
|
/**
|
|
@@ -802,43 +818,66 @@ var OpenFeatureCommonAPI = class {
|
|
|
802
818
|
getHandlers(eventType) {
|
|
803
819
|
return this._events.getHandlers(eventType);
|
|
804
820
|
}
|
|
821
|
+
setProviderAndWait(clientOrProvider, providerOrUndefined) {
|
|
822
|
+
return __async(this, null, function* () {
|
|
823
|
+
yield this.setAwaitableProvider(clientOrProvider, providerOrUndefined);
|
|
824
|
+
});
|
|
825
|
+
}
|
|
805
826
|
setProvider(clientOrProvider, providerOrUndefined) {
|
|
806
|
-
|
|
827
|
+
const maybePromise = this.setAwaitableProvider(clientOrProvider, providerOrUndefined);
|
|
828
|
+
if (maybePromise) {
|
|
829
|
+
maybePromise.catch(() => {
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
return this;
|
|
833
|
+
}
|
|
834
|
+
setAwaitableProvider(clientOrProvider, providerOrUndefined) {
|
|
835
|
+
var _a, _b, _c, _d, _e, _f;
|
|
807
836
|
const clientName = stringOrUndefined(clientOrProvider);
|
|
808
837
|
const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined);
|
|
809
838
|
if (!provider) {
|
|
810
|
-
|
|
839
|
+
this._logger.debug("No provider defined, ignoring setProvider call");
|
|
840
|
+
return;
|
|
811
841
|
}
|
|
812
842
|
const oldProvider = this.getProviderForClient(clientName);
|
|
843
|
+
const providerName = provider.metadata.name;
|
|
813
844
|
if (oldProvider === provider) {
|
|
814
|
-
|
|
845
|
+
this._logger.debug("Provider is already set, ignoring setProvider call");
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
if (!provider.runsOn) {
|
|
849
|
+
this._logger.debug(`Provider '${provider.metadata.name}' has not defined its intended use.`);
|
|
850
|
+
} else if (provider.runsOn !== this._runsOn) {
|
|
851
|
+
throw new GeneralError(`Provider '${provider.metadata.name}' is intended for use on the ${provider.runsOn}.`);
|
|
815
852
|
}
|
|
816
853
|
const emitters = this.getAssociatedEventEmitters(clientName);
|
|
817
854
|
if (typeof provider.initialize === "function" && provider.status === void 0) {
|
|
818
855
|
const activeLogger = this._logger || console;
|
|
819
856
|
activeLogger.warn(
|
|
820
|
-
`Provider ${
|
|
857
|
+
`Provider ${providerName} implements 'initialize' but not 'status'. Please implement 'status'.`
|
|
821
858
|
);
|
|
822
859
|
}
|
|
860
|
+
let initializationPromise = void 0;
|
|
823
861
|
if ((provider == null ? void 0 : provider.status) === "NOT_READY" /* NOT_READY */ && typeof provider.initialize === "function") {
|
|
824
|
-
|
|
862
|
+
initializationPromise = (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => {
|
|
825
863
|
var _a2;
|
|
826
864
|
this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
|
|
827
|
-
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName });
|
|
865
|
+
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
|
|
828
866
|
});
|
|
829
|
-
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName });
|
|
830
|
-
})) == null ? void 0 :
|
|
867
|
+
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
|
|
868
|
+
})) == null ? void 0 : _d.catch((error) => {
|
|
831
869
|
var _a2;
|
|
832
870
|
this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
|
|
833
|
-
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
|
|
871
|
+
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message });
|
|
834
872
|
});
|
|
835
|
-
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message });
|
|
873
|
+
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message });
|
|
874
|
+
throw error;
|
|
836
875
|
});
|
|
837
876
|
} else {
|
|
838
877
|
emitters.forEach((emitter) => {
|
|
839
|
-
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName });
|
|
878
|
+
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
|
|
840
879
|
});
|
|
841
|
-
(
|
|
880
|
+
(_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
|
|
842
881
|
}
|
|
843
882
|
if (clientName) {
|
|
844
883
|
this._clientProviders.set(clientName, provider);
|
|
@@ -847,9 +886,9 @@ var OpenFeatureCommonAPI = class {
|
|
|
847
886
|
}
|
|
848
887
|
this.transferListeners(oldProvider, provider, clientName, emitters);
|
|
849
888
|
if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) {
|
|
850
|
-
(
|
|
889
|
+
(_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider);
|
|
851
890
|
}
|
|
852
|
-
return
|
|
891
|
+
return initializationPromise;
|
|
853
892
|
}
|
|
854
893
|
getProviderForClient(name) {
|
|
855
894
|
var _a;
|
|
@@ -870,7 +909,7 @@ var OpenFeatureCommonAPI = class {
|
|
|
870
909
|
(eventType) => {
|
|
871
910
|
var _a;
|
|
872
911
|
return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () {
|
|
873
|
-
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name }));
|
|
912
|
+
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name, providerName: clientProvider.metadata.name }));
|
|
874
913
|
}));
|
|
875
914
|
}
|
|
876
915
|
);
|
|
@@ -899,9 +938,9 @@ var OpenFeatureCommonAPI = class {
|
|
|
899
938
|
const newClientHandlers = Object.values(ProviderEvents).map((eventType) => {
|
|
900
939
|
const handler = (details) => __async(this, null, function* () {
|
|
901
940
|
emitters.forEach((emitter) => {
|
|
902
|
-
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
|
|
941
|
+
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name }));
|
|
903
942
|
});
|
|
904
|
-
this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName }));
|
|
943
|
+
this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name }));
|
|
905
944
|
});
|
|
906
945
|
return [eventType, handler];
|
|
907
946
|
});
|
|
@@ -926,40 +965,28 @@ var OpenFeatureCommonAPI = class {
|
|
|
926
965
|
try {
|
|
927
966
|
yield (_a2 = provider.onClose) == null ? void 0 : _a2.call(provider);
|
|
928
967
|
} catch (err) {
|
|
929
|
-
this.handleShutdownError(
|
|
968
|
+
this.handleShutdownError(provider, err);
|
|
930
969
|
}
|
|
931
970
|
}))
|
|
932
971
|
);
|
|
933
972
|
});
|
|
934
973
|
}
|
|
974
|
+
clearProvidersAndSetDefault(defaultProvider) {
|
|
975
|
+
return __async(this, null, function* () {
|
|
976
|
+
try {
|
|
977
|
+
yield this.close();
|
|
978
|
+
} catch (err) {
|
|
979
|
+
this._logger.error("Unable to cleanly close providers. Resetting to the default configuration.");
|
|
980
|
+
} finally {
|
|
981
|
+
this._clientProviders.clear();
|
|
982
|
+
this._defaultProvider = defaultProvider;
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
}
|
|
935
986
|
handleShutdownError(provider, err) {
|
|
936
987
|
this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`);
|
|
937
988
|
this._logger.error(err == null ? void 0 : err.stack);
|
|
938
989
|
}
|
|
939
|
-
setTransactionContextPropagator(transactionContextPropagator) {
|
|
940
|
-
const baseMessage = "Invalid TransactionContextPropagator, will not be set: ";
|
|
941
|
-
if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.getTransactionContext) !== "function") {
|
|
942
|
-
this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);
|
|
943
|
-
} else if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.setTransactionContext) !== "function") {
|
|
944
|
-
this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);
|
|
945
|
-
} else {
|
|
946
|
-
this._transactionContextPropagator = transactionContextPropagator;
|
|
947
|
-
}
|
|
948
|
-
return this;
|
|
949
|
-
}
|
|
950
|
-
setTransactionContext(transactionContext, callback, ...args) {
|
|
951
|
-
this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);
|
|
952
|
-
}
|
|
953
|
-
getTransactionContext() {
|
|
954
|
-
try {
|
|
955
|
-
return this._transactionContextPropagator.getTransactionContext();
|
|
956
|
-
} catch (err) {
|
|
957
|
-
const error = err;
|
|
958
|
-
this._logger.error(`Error getting transaction context: ${error == null ? void 0 : error.message}, returning empty context.`);
|
|
959
|
-
this._logger.error(error == null ? void 0 : error.stack);
|
|
960
|
-
return {};
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
990
|
};
|
|
964
991
|
|
|
965
992
|
// src/provider/no-op-provider.ts
|
|
@@ -1000,7 +1027,7 @@ var _globalThis = globalThis;
|
|
|
1000
1027
|
var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
|
|
1001
1028
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1002
1029
|
constructor() {
|
|
1003
|
-
super();
|
|
1030
|
+
super("client");
|
|
1004
1031
|
this._defaultProvider = NOOP_PROVIDER;
|
|
1005
1032
|
}
|
|
1006
1033
|
/**
|
|
@@ -1058,6 +1085,13 @@ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
|
|
|
1058
1085
|
{ name, version }
|
|
1059
1086
|
);
|
|
1060
1087
|
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Clears all registered providers and resets the default provider.
|
|
1090
|
+
* @returns {Promise<void>}
|
|
1091
|
+
*/
|
|
1092
|
+
clearProviders() {
|
|
1093
|
+
return super.clearProvidersAndSetDefault(NOOP_PROVIDER);
|
|
1094
|
+
}
|
|
1061
1095
|
};
|
|
1062
1096
|
var OpenFeature = OpenFeatureAPI.getInstance();
|
|
1063
1097
|
|
|
@@ -1083,7 +1117,7 @@ var OpenFeatureClient = class {
|
|
|
1083
1117
|
const providerReady = !this._provider.status || this._provider.status === "READY" /* READY */;
|
|
1084
1118
|
if (eventType === "PROVIDER_READY" /* Ready */ && providerReady) {
|
|
1085
1119
|
try {
|
|
1086
|
-
handler({ clientName: this.metadata.name });
|
|
1120
|
+
handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });
|
|
1087
1121
|
} catch (err) {
|
|
1088
1122
|
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
|
|
1089
1123
|
}
|