@openfeature/core
Advanced tools
Comparing version
"use strict"; | ||
var __defProp = Object.defineProperty; | ||
var __defProps = Object.defineProperties; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropDescs = Object.getOwnPropertyDescriptors; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __spreadValues = (a, b) => { | ||
for (var prop in b || (b = {})) | ||
if (__hasOwnProp.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
if (__getOwnPropSymbols) | ||
for (var prop of __getOwnPropSymbols(b)) { | ||
if (__propIsEnum.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
} | ||
return a; | ||
}; | ||
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
var __export = (target, all) => { | ||
@@ -19,2 +36,22 @@ for (var name in all) | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
var __async = (__this, __arguments, generator) => { | ||
return new Promise((resolve, reject) => { | ||
var fulfilled = (value) => { | ||
try { | ||
step(generator.next(value)); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}; | ||
var rejected = (value) => { | ||
try { | ||
step(generator.throw(value)); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}; | ||
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); | ||
step((generator = generator.apply(__this, __arguments)).next()); | ||
}); | ||
}; | ||
@@ -112,5 +149,6 @@ // src/index.ts | ||
constructor(message, options) { | ||
super(message, options); | ||
super(message); | ||
Object.setPrototypeOf(this, _OpenFeatureError.prototype); | ||
this.name = "OpenFeatureError"; | ||
this.cause = options == null ? void 0 : options.cause; | ||
} | ||
@@ -121,3 +159,2 @@ }; | ||
var FlagNotFoundError = class _FlagNotFoundError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -133,3 +170,2 @@ super(message, options); | ||
var GeneralError = class _GeneralError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -145,3 +181,2 @@ super(message, options); | ||
var InvalidContextError = class _InvalidContextError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -157,3 +192,2 @@ super(message, options); | ||
var ParseError = class _ParseError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -169,3 +203,2 @@ super(message, options); | ||
var ProviderFatalError = class _ProviderFatalError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -181,3 +214,2 @@ super(message, options); | ||
var ProviderNotReadyError = class _ProviderNotReadyError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -193,3 +225,2 @@ super(message, options); | ||
var TargetingKeyMissingError = class _TargetingKeyMissingError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -205,3 +236,2 @@ super(message, options); | ||
var TypeMismatchError = class _TypeMismatchError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -304,5 +334,4 @@ super(message, options); | ||
var SafeLogger = class { | ||
logger; | ||
fallbackLogger = new DefaultLogger(); | ||
constructor(logger) { | ||
this.fallbackLogger = new DefaultLogger(); | ||
try { | ||
@@ -346,12 +375,11 @@ for (const level of LOG_LEVELS) { | ||
this.globalLogger = globalLogger; | ||
this._handlers = { | ||
["PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_CONTEXT_CHANGED" /* ContextChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_READY" /* Ready */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_ERROR" /* Error */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_STALE" /* Stale */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_RECONCILING" /* Reconciling */]: /* @__PURE__ */ new WeakMap() | ||
}; | ||
} | ||
_handlers = { | ||
["PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_CONTEXT_CHANGED" /* ContextChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_READY" /* Ready */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_ERROR" /* Error */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_STALE" /* Stale */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_RECONCILING" /* Reconciling */]: /* @__PURE__ */ new WeakMap() | ||
}; | ||
_eventLogger; | ||
// here we use E, to restrict the events a provider can manually emit (PROVIDER_CONTEXT_CHANGED is emitted by the SDK) | ||
@@ -362,9 +390,10 @@ emit(eventType, context) { | ||
addHandler(eventType, handler) { | ||
const asyncHandler = async (details) => { | ||
const asyncHandler = (details) => __async(this, null, function* () { | ||
var _a; | ||
try { | ||
await handler(details); | ||
yield handler(details); | ||
} catch (err) { | ||
this._logger?.error("Error running event handler:", err); | ||
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
} | ||
}; | ||
}); | ||
const existingAsyncHandlers = this._handlers[eventType].get(handler); | ||
@@ -398,3 +427,4 @@ this._handlers[eventType].set(handler, [...existingAsyncHandlers || [], asyncHandler]); | ||
get _logger() { | ||
return this._eventLogger ?? this.globalLogger?.(); | ||
var _a, _b; | ||
return (_b = this._eventLogger) != null ? _b : (_a = this.globalLogger) == null ? void 0 : _a.call(this); | ||
} | ||
@@ -427,10 +457,12 @@ }; | ||
this._status = _status; | ||
_provider.events?.addHandler("PROVIDER_READY" /* Ready */, () => { | ||
this._pendingContextChanges = 0; | ||
var _a, _b, _c; | ||
(_a = _provider.events) == null ? void 0 : _a.addHandler("PROVIDER_READY" /* Ready */, () => { | ||
this._status = _statusEnumType.READY; | ||
}); | ||
_provider.events?.addHandler("PROVIDER_STALE" /* Stale */, () => { | ||
(_b = _provider.events) == null ? void 0 : _b.addHandler("PROVIDER_STALE" /* Stale */, () => { | ||
this._status = _statusEnumType.STALE; | ||
}); | ||
_provider.events?.addHandler("PROVIDER_ERROR" /* Error */, (details) => { | ||
if (details?.errorCode === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
(_c = _provider.events) == null ? void 0 : _c.addHandler("PROVIDER_ERROR" /* Error */, (details) => { | ||
if ((details == null ? void 0 : details.errorCode) === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
this._status = _statusEnumType.FATAL; | ||
@@ -442,3 +474,2 @@ } else { | ||
} | ||
_pendingContextChanges = 0; | ||
get provider() { | ||
@@ -467,10 +498,9 @@ return this._provider; | ||
var OpenFeatureCommonAPI = class { | ||
_hooks = []; | ||
_context = {}; | ||
_logger = new DefaultLogger(); | ||
_clientEventHandlers = /* @__PURE__ */ new Map(); | ||
_domainScopedContext = /* @__PURE__ */ new Map(); | ||
_clientEvents = /* @__PURE__ */ new Map(); | ||
_runsOn; | ||
constructor(category) { | ||
this._hooks = []; | ||
this._context = {}; | ||
this._logger = new DefaultLogger(); | ||
this._clientEventHandlers = /* @__PURE__ */ new Map(); | ||
this._domainScopedContext = /* @__PURE__ */ new Map(); | ||
this._clientEvents = /* @__PURE__ */ new Map(); | ||
this._runsOn = category; | ||
@@ -518,2 +548,3 @@ } | ||
[.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._domainScopedProviders].forEach((keyProviderTuple) => { | ||
var _a; | ||
const domain = keyProviderTuple[0]; | ||
@@ -527,3 +558,3 @@ const provider = keyProviderTuple[1].provider; | ||
} catch (err) { | ||
this._logger?.error("Error running event handler:", err); | ||
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
} | ||
@@ -557,4 +588,5 @@ } | ||
setAwaitableProvider(domainOrProvider, providerOrUndefined) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
const domain = stringOrUndefined(domainOrProvider); | ||
const provider = objectOrUndefined(domainOrProvider) ?? objectOrUndefined(providerOrUndefined); | ||
const provider = (_a = objectOrUndefined(domainOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined); | ||
if (!provider) { | ||
@@ -583,10 +615,12 @@ this._logger.debug("No provider defined, ignoring setProvider call"); | ||
if (typeof provider.initialize === "function" && !this.allProviders.includes(provider)) { | ||
initializationPromise = provider.initialize?.(domain ? this._domainScopedContext.get(domain) ?? this._context : this._context)?.then(() => { | ||
initializationPromise = (_e = (_d = (_c = provider.initialize) == null ? void 0 : _c.call(provider, domain ? (_b = this._domainScopedContext.get(domain)) != null ? _b : this._context : this._context)) == null ? void 0 : _d.then(() => { | ||
var _a2; | ||
wrappedProvider.status = this._statusEnumType.READY; | ||
this.getAssociatedEventEmitters(domain).forEach((emitter) => { | ||
emitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
}); | ||
this._apiEmitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
})?.catch((error) => { | ||
if (error?.code === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
(_a2 = this._apiEmitter) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
})) == null ? void 0 : _e.catch((error) => { | ||
var _a2; | ||
if ((error == null ? void 0 : error.code) === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
wrappedProvider.status = this._statusEnumType.FATAL; | ||
@@ -597,14 +631,14 @@ } else { | ||
this.getAssociatedEventEmitters(domain).forEach((emitter) => { | ||
emitter?.emit("PROVIDER_ERROR" /* Error */, { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { | ||
clientName: domain, | ||
domain, | ||
providerName, | ||
message: error?.message | ||
message: error == null ? void 0 : error.message | ||
}); | ||
}); | ||
this._apiEmitter?.emit("PROVIDER_ERROR" /* Error */, { | ||
(_a2 = this._apiEmitter) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { | ||
clientName: domain, | ||
domain, | ||
providerName, | ||
message: error?.message | ||
message: error == null ? void 0 : error.message | ||
}); | ||
@@ -616,5 +650,5 @@ throw error; | ||
emitters.forEach((emitter) => { | ||
emitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
}); | ||
this._apiEmitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
(_f = this._apiEmitter) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
} | ||
@@ -628,4 +662,4 @@ if (domain) { | ||
if (!this.allProviders.includes(oldProvider)) { | ||
oldProvider?.onClose?.()?.catch((err) => { | ||
this._logger.error(`error closing provider: ${err?.message}, ${err?.stack}`); | ||
(_h = (_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider)) == null ? void 0 : _h.catch((err) => { | ||
this._logger.error(`error closing provider: ${err == null ? void 0 : err.message}, ${err == null ? void 0 : err.stack}`); | ||
}); | ||
@@ -636,6 +670,7 @@ } | ||
getProviderForClient(domain) { | ||
var _a, _b; | ||
if (!domain) { | ||
return this._defaultProvider.provider; | ||
} | ||
return this._domainScopedProviders.get(domain)?.provider ?? this._defaultProvider.provider; | ||
return (_b = (_a = this._domainScopedProviders.get(domain)) == null ? void 0 : _a.provider) != null ? _b : this._defaultProvider.provider; | ||
} | ||
@@ -651,10 +686,12 @@ buildAndCacheEventEmitterForClient(domain) { | ||
Object.values(ClientProviderEvents).forEach( | ||
(eventType) => clientProvider.events?.addHandler(eventType, async (details) => { | ||
newEmitter.emit(eventType, { | ||
...details, | ||
clientName: domain, | ||
domain, | ||
providerName: clientProvider.metadata.name | ||
}); | ||
}) | ||
(eventType) => { | ||
var _a; | ||
return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () { | ||
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { | ||
clientName: domain, | ||
domain, | ||
providerName: clientProvider.metadata.name | ||
})); | ||
})); | ||
} | ||
); | ||
@@ -678,51 +715,63 @@ return newEmitter; | ||
transferListeners(oldProvider, newProvider, domain, emitters) { | ||
this._clientEventHandlers.get(domain)?.forEach((eventHandler) => oldProvider.events?.removeHandler(...eventHandler)); | ||
var _a; | ||
(_a = this._clientEventHandlers.get(domain)) == null ? void 0 : _a.forEach((eventHandler) => { | ||
var _a2; | ||
return (_a2 = oldProvider.events) == null ? void 0 : _a2.removeHandler(...eventHandler); | ||
}); | ||
const newClientHandlers = Object.values(ClientProviderEvents).map((eventType) => { | ||
const handler = async (details) => { | ||
const handler = (details) => __async(this, null, function* () { | ||
emitters.forEach((emitter) => { | ||
emitter?.emit(eventType, { ...details, clientName: domain, domain, providerName: newProvider.metadata.name }); | ||
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: domain, domain, providerName: newProvider.metadata.name })); | ||
}); | ||
this._apiEmitter.emit(eventType, { | ||
...details, | ||
this._apiEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { | ||
clientName: domain, | ||
domain, | ||
providerName: newProvider.metadata.name | ||
}); | ||
}; | ||
})); | ||
}); | ||
return [eventType, handler]; | ||
}); | ||
this._clientEventHandlers.set(domain, newClientHandlers); | ||
newClientHandlers.forEach((eventHandler) => newProvider.events?.addHandler(...eventHandler)); | ||
newClientHandlers.forEach((eventHandler) => { | ||
var _a2; | ||
return (_a2 = newProvider.events) == null ? void 0 : _a2.addHandler(...eventHandler); | ||
}); | ||
} | ||
async close() { | ||
try { | ||
await this?._defaultProvider.provider?.onClose?.(); | ||
} catch (err) { | ||
this.handleShutdownError(this._defaultProvider.provider, err); | ||
} | ||
const wrappers = Array.from(this._domainScopedProviders); | ||
await Promise.all( | ||
wrappers.map(async ([, wrapper]) => { | ||
try { | ||
await wrapper?.provider.onClose?.(); | ||
} catch (err) { | ||
this.handleShutdownError(wrapper?.provider, err); | ||
} | ||
}) | ||
); | ||
} | ||
async clearProvidersAndSetDefault(defaultProvider) { | ||
try { | ||
await this.close(); | ||
} catch (err) { | ||
this._logger.error("Unable to cleanly close providers. Resetting to the default configuration."); | ||
} finally { | ||
this._domainScopedProviders.clear(); | ||
this._defaultProvider = new ProviderWrapper( | ||
defaultProvider, | ||
this._statusEnumType.NOT_READY, | ||
this._statusEnumType | ||
close() { | ||
return __async(this, null, function* () { | ||
var _a, _b; | ||
try { | ||
yield (_b = (_a = this == null ? void 0 : this._defaultProvider.provider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a); | ||
} catch (err) { | ||
this.handleShutdownError(this._defaultProvider.provider, err); | ||
} | ||
const wrappers = Array.from(this._domainScopedProviders); | ||
yield Promise.all( | ||
wrappers.map((_0) => __async(this, [_0], function* ([, wrapper]) { | ||
var _a2, _b2; | ||
try { | ||
yield (_b2 = wrapper == null ? void 0 : (_a2 = wrapper.provider).onClose) == null ? void 0 : _b2.call(_a2); | ||
} catch (err) { | ||
this.handleShutdownError(wrapper == null ? void 0 : wrapper.provider, err); | ||
} | ||
})) | ||
); | ||
} | ||
}); | ||
} | ||
clearProvidersAndSetDefault(defaultProvider) { | ||
return __async(this, null, function* () { | ||
try { | ||
yield this.close(); | ||
} catch (err) { | ||
this._logger.error("Unable to cleanly close providers. Resetting to the default configuration."); | ||
} finally { | ||
this._domainScopedProviders.clear(); | ||
this._defaultProvider = new ProviderWrapper( | ||
defaultProvider, | ||
this._statusEnumType.NOT_READY, | ||
this._statusEnumType | ||
); | ||
} | ||
}); | ||
} | ||
get allProviders() { | ||
@@ -736,5 +785,5 @@ return [ | ||
this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`); | ||
this._logger.error(err?.stack); | ||
this._logger.error(err == null ? void 0 : err.stack); | ||
} | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -0,1 +1,41 @@ | ||
var __defProp = Object.defineProperty; | ||
var __defProps = Object.defineProperties; | ||
var __getOwnPropDescs = Object.getOwnPropertyDescriptors; | ||
var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __spreadValues = (a, b) => { | ||
for (var prop in b || (b = {})) | ||
if (__hasOwnProp.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
if (__getOwnPropSymbols) | ||
for (var prop of __getOwnPropSymbols(b)) { | ||
if (__propIsEnum.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
} | ||
return a; | ||
}; | ||
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
var __async = (__this, __arguments, generator) => { | ||
return new Promise((resolve, reject) => { | ||
var fulfilled = (value) => { | ||
try { | ||
step(generator.next(value)); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}; | ||
var rejected = (value) => { | ||
try { | ||
step(generator.throw(value)); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
}; | ||
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); | ||
step((generator = generator.apply(__this, __arguments)).next()); | ||
}); | ||
}; | ||
// src/evaluation/evaluation.ts | ||
@@ -57,5 +97,6 @@ var StandardResolutionReasons = { | ||
constructor(message, options) { | ||
super(message, options); | ||
super(message); | ||
Object.setPrototypeOf(this, _OpenFeatureError.prototype); | ||
this.name = "OpenFeatureError"; | ||
this.cause = options == null ? void 0 : options.cause; | ||
} | ||
@@ -66,3 +107,2 @@ }; | ||
var FlagNotFoundError = class _FlagNotFoundError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -78,3 +118,2 @@ super(message, options); | ||
var GeneralError = class _GeneralError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -90,3 +129,2 @@ super(message, options); | ||
var InvalidContextError = class _InvalidContextError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -102,3 +140,2 @@ super(message, options); | ||
var ParseError = class _ParseError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -114,3 +151,2 @@ super(message, options); | ||
var ProviderFatalError = class _ProviderFatalError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -126,3 +162,2 @@ super(message, options); | ||
var ProviderNotReadyError = class _ProviderNotReadyError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -138,3 +173,2 @@ super(message, options); | ||
var TargetingKeyMissingError = class _TargetingKeyMissingError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -150,3 +184,2 @@ super(message, options); | ||
var TypeMismatchError = class _TypeMismatchError extends OpenFeatureError { | ||
code; | ||
constructor(message, options) { | ||
@@ -249,5 +282,4 @@ super(message, options); | ||
var SafeLogger = class { | ||
logger; | ||
fallbackLogger = new DefaultLogger(); | ||
constructor(logger) { | ||
this.fallbackLogger = new DefaultLogger(); | ||
try { | ||
@@ -291,12 +323,11 @@ for (const level of LOG_LEVELS) { | ||
this.globalLogger = globalLogger; | ||
this._handlers = { | ||
["PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_CONTEXT_CHANGED" /* ContextChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_READY" /* Ready */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_ERROR" /* Error */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_STALE" /* Stale */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_RECONCILING" /* Reconciling */]: /* @__PURE__ */ new WeakMap() | ||
}; | ||
} | ||
_handlers = { | ||
["PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_CONTEXT_CHANGED" /* ContextChanged */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_READY" /* Ready */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_ERROR" /* Error */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_STALE" /* Stale */]: /* @__PURE__ */ new WeakMap(), | ||
["PROVIDER_RECONCILING" /* Reconciling */]: /* @__PURE__ */ new WeakMap() | ||
}; | ||
_eventLogger; | ||
// here we use E, to restrict the events a provider can manually emit (PROVIDER_CONTEXT_CHANGED is emitted by the SDK) | ||
@@ -307,9 +338,10 @@ emit(eventType, context) { | ||
addHandler(eventType, handler) { | ||
const asyncHandler = async (details) => { | ||
const asyncHandler = (details) => __async(this, null, function* () { | ||
var _a; | ||
try { | ||
await handler(details); | ||
yield handler(details); | ||
} catch (err) { | ||
this._logger?.error("Error running event handler:", err); | ||
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
} | ||
}; | ||
}); | ||
const existingAsyncHandlers = this._handlers[eventType].get(handler); | ||
@@ -343,3 +375,4 @@ this._handlers[eventType].set(handler, [...existingAsyncHandlers || [], asyncHandler]); | ||
get _logger() { | ||
return this._eventLogger ?? this.globalLogger?.(); | ||
var _a, _b; | ||
return (_b = this._eventLogger) != null ? _b : (_a = this.globalLogger) == null ? void 0 : _a.call(this); | ||
} | ||
@@ -372,10 +405,12 @@ }; | ||
this._status = _status; | ||
_provider.events?.addHandler("PROVIDER_READY" /* Ready */, () => { | ||
this._pendingContextChanges = 0; | ||
var _a, _b, _c; | ||
(_a = _provider.events) == null ? void 0 : _a.addHandler("PROVIDER_READY" /* Ready */, () => { | ||
this._status = _statusEnumType.READY; | ||
}); | ||
_provider.events?.addHandler("PROVIDER_STALE" /* Stale */, () => { | ||
(_b = _provider.events) == null ? void 0 : _b.addHandler("PROVIDER_STALE" /* Stale */, () => { | ||
this._status = _statusEnumType.STALE; | ||
}); | ||
_provider.events?.addHandler("PROVIDER_ERROR" /* Error */, (details) => { | ||
if (details?.errorCode === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
(_c = _provider.events) == null ? void 0 : _c.addHandler("PROVIDER_ERROR" /* Error */, (details) => { | ||
if ((details == null ? void 0 : details.errorCode) === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
this._status = _statusEnumType.FATAL; | ||
@@ -387,3 +422,2 @@ } else { | ||
} | ||
_pendingContextChanges = 0; | ||
get provider() { | ||
@@ -412,10 +446,9 @@ return this._provider; | ||
var OpenFeatureCommonAPI = class { | ||
_hooks = []; | ||
_context = {}; | ||
_logger = new DefaultLogger(); | ||
_clientEventHandlers = /* @__PURE__ */ new Map(); | ||
_domainScopedContext = /* @__PURE__ */ new Map(); | ||
_clientEvents = /* @__PURE__ */ new Map(); | ||
_runsOn; | ||
constructor(category) { | ||
this._hooks = []; | ||
this._context = {}; | ||
this._logger = new DefaultLogger(); | ||
this._clientEventHandlers = /* @__PURE__ */ new Map(); | ||
this._domainScopedContext = /* @__PURE__ */ new Map(); | ||
this._clientEvents = /* @__PURE__ */ new Map(); | ||
this._runsOn = category; | ||
@@ -463,2 +496,3 @@ } | ||
[.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._domainScopedProviders].forEach((keyProviderTuple) => { | ||
var _a; | ||
const domain = keyProviderTuple[0]; | ||
@@ -472,3 +506,3 @@ const provider = keyProviderTuple[1].provider; | ||
} catch (err) { | ||
this._logger?.error("Error running event handler:", err); | ||
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
} | ||
@@ -502,4 +536,5 @@ } | ||
setAwaitableProvider(domainOrProvider, providerOrUndefined) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h; | ||
const domain = stringOrUndefined(domainOrProvider); | ||
const provider = objectOrUndefined(domainOrProvider) ?? objectOrUndefined(providerOrUndefined); | ||
const provider = (_a = objectOrUndefined(domainOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined); | ||
if (!provider) { | ||
@@ -528,10 +563,12 @@ this._logger.debug("No provider defined, ignoring setProvider call"); | ||
if (typeof provider.initialize === "function" && !this.allProviders.includes(provider)) { | ||
initializationPromise = provider.initialize?.(domain ? this._domainScopedContext.get(domain) ?? this._context : this._context)?.then(() => { | ||
initializationPromise = (_e = (_d = (_c = provider.initialize) == null ? void 0 : _c.call(provider, domain ? (_b = this._domainScopedContext.get(domain)) != null ? _b : this._context : this._context)) == null ? void 0 : _d.then(() => { | ||
var _a2; | ||
wrappedProvider.status = this._statusEnumType.READY; | ||
this.getAssociatedEventEmitters(domain).forEach((emitter) => { | ||
emitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
}); | ||
this._apiEmitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
})?.catch((error) => { | ||
if (error?.code === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
(_a2 = this._apiEmitter) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
})) == null ? void 0 : _e.catch((error) => { | ||
var _a2; | ||
if ((error == null ? void 0 : error.code) === "PROVIDER_FATAL" /* PROVIDER_FATAL */) { | ||
wrappedProvider.status = this._statusEnumType.FATAL; | ||
@@ -542,14 +579,14 @@ } else { | ||
this.getAssociatedEventEmitters(domain).forEach((emitter) => { | ||
emitter?.emit("PROVIDER_ERROR" /* Error */, { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { | ||
clientName: domain, | ||
domain, | ||
providerName, | ||
message: error?.message | ||
message: error == null ? void 0 : error.message | ||
}); | ||
}); | ||
this._apiEmitter?.emit("PROVIDER_ERROR" /* Error */, { | ||
(_a2 = this._apiEmitter) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { | ||
clientName: domain, | ||
domain, | ||
providerName, | ||
message: error?.message | ||
message: error == null ? void 0 : error.message | ||
}); | ||
@@ -561,5 +598,5 @@ throw error; | ||
emitters.forEach((emitter) => { | ||
emitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
}); | ||
this._apiEmitter?.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
(_f = this._apiEmitter) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */, { clientName: domain, domain, providerName }); | ||
} | ||
@@ -573,4 +610,4 @@ if (domain) { | ||
if (!this.allProviders.includes(oldProvider)) { | ||
oldProvider?.onClose?.()?.catch((err) => { | ||
this._logger.error(`error closing provider: ${err?.message}, ${err?.stack}`); | ||
(_h = (_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider)) == null ? void 0 : _h.catch((err) => { | ||
this._logger.error(`error closing provider: ${err == null ? void 0 : err.message}, ${err == null ? void 0 : err.stack}`); | ||
}); | ||
@@ -581,6 +618,7 @@ } | ||
getProviderForClient(domain) { | ||
var _a, _b; | ||
if (!domain) { | ||
return this._defaultProvider.provider; | ||
} | ||
return this._domainScopedProviders.get(domain)?.provider ?? this._defaultProvider.provider; | ||
return (_b = (_a = this._domainScopedProviders.get(domain)) == null ? void 0 : _a.provider) != null ? _b : this._defaultProvider.provider; | ||
} | ||
@@ -596,10 +634,12 @@ buildAndCacheEventEmitterForClient(domain) { | ||
Object.values(ClientProviderEvents).forEach( | ||
(eventType) => clientProvider.events?.addHandler(eventType, async (details) => { | ||
newEmitter.emit(eventType, { | ||
...details, | ||
clientName: domain, | ||
domain, | ||
providerName: clientProvider.metadata.name | ||
}); | ||
}) | ||
(eventType) => { | ||
var _a; | ||
return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () { | ||
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { | ||
clientName: domain, | ||
domain, | ||
providerName: clientProvider.metadata.name | ||
})); | ||
})); | ||
} | ||
); | ||
@@ -623,51 +663,63 @@ return newEmitter; | ||
transferListeners(oldProvider, newProvider, domain, emitters) { | ||
this._clientEventHandlers.get(domain)?.forEach((eventHandler) => oldProvider.events?.removeHandler(...eventHandler)); | ||
var _a; | ||
(_a = this._clientEventHandlers.get(domain)) == null ? void 0 : _a.forEach((eventHandler) => { | ||
var _a2; | ||
return (_a2 = oldProvider.events) == null ? void 0 : _a2.removeHandler(...eventHandler); | ||
}); | ||
const newClientHandlers = Object.values(ClientProviderEvents).map((eventType) => { | ||
const handler = async (details) => { | ||
const handler = (details) => __async(this, null, function* () { | ||
emitters.forEach((emitter) => { | ||
emitter?.emit(eventType, { ...details, clientName: domain, domain, providerName: newProvider.metadata.name }); | ||
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: domain, domain, providerName: newProvider.metadata.name })); | ||
}); | ||
this._apiEmitter.emit(eventType, { | ||
...details, | ||
this._apiEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { | ||
clientName: domain, | ||
domain, | ||
providerName: newProvider.metadata.name | ||
}); | ||
}; | ||
})); | ||
}); | ||
return [eventType, handler]; | ||
}); | ||
this._clientEventHandlers.set(domain, newClientHandlers); | ||
newClientHandlers.forEach((eventHandler) => newProvider.events?.addHandler(...eventHandler)); | ||
newClientHandlers.forEach((eventHandler) => { | ||
var _a2; | ||
return (_a2 = newProvider.events) == null ? void 0 : _a2.addHandler(...eventHandler); | ||
}); | ||
} | ||
async close() { | ||
try { | ||
await this?._defaultProvider.provider?.onClose?.(); | ||
} catch (err) { | ||
this.handleShutdownError(this._defaultProvider.provider, err); | ||
} | ||
const wrappers = Array.from(this._domainScopedProviders); | ||
await Promise.all( | ||
wrappers.map(async ([, wrapper]) => { | ||
try { | ||
await wrapper?.provider.onClose?.(); | ||
} catch (err) { | ||
this.handleShutdownError(wrapper?.provider, err); | ||
} | ||
}) | ||
); | ||
} | ||
async clearProvidersAndSetDefault(defaultProvider) { | ||
try { | ||
await this.close(); | ||
} catch (err) { | ||
this._logger.error("Unable to cleanly close providers. Resetting to the default configuration."); | ||
} finally { | ||
this._domainScopedProviders.clear(); | ||
this._defaultProvider = new ProviderWrapper( | ||
defaultProvider, | ||
this._statusEnumType.NOT_READY, | ||
this._statusEnumType | ||
close() { | ||
return __async(this, null, function* () { | ||
var _a, _b; | ||
try { | ||
yield (_b = (_a = this == null ? void 0 : this._defaultProvider.provider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a); | ||
} catch (err) { | ||
this.handleShutdownError(this._defaultProvider.provider, err); | ||
} | ||
const wrappers = Array.from(this._domainScopedProviders); | ||
yield Promise.all( | ||
wrappers.map((_0) => __async(this, [_0], function* ([, wrapper]) { | ||
var _a2, _b2; | ||
try { | ||
yield (_b2 = wrapper == null ? void 0 : (_a2 = wrapper.provider).onClose) == null ? void 0 : _b2.call(_a2); | ||
} catch (err) { | ||
this.handleShutdownError(wrapper == null ? void 0 : wrapper.provider, err); | ||
} | ||
})) | ||
); | ||
} | ||
}); | ||
} | ||
clearProvidersAndSetDefault(defaultProvider) { | ||
return __async(this, null, function* () { | ||
try { | ||
yield this.close(); | ||
} catch (err) { | ||
this._logger.error("Unable to cleanly close providers. Resetting to the default configuration."); | ||
} finally { | ||
this._domainScopedProviders.clear(); | ||
this._defaultProvider = new ProviderWrapper( | ||
defaultProvider, | ||
this._statusEnumType.NOT_READY, | ||
this._statusEnumType | ||
); | ||
} | ||
}); | ||
} | ||
get allProviders() { | ||
@@ -681,3 +733,3 @@ return [ | ||
this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`); | ||
this._logger.error(err?.stack); | ||
this._logger.error(err == null ? void 0 : err.stack); | ||
} | ||
@@ -684,0 +736,0 @@ }; |
@@ -546,4 +546,12 @@ type FlagValueType = 'boolean' | 'string' | 'number' | 'object'; | ||
/** | ||
* Error Options were added in ES2022. Manually adding the type so that an | ||
* earlier target can be used. | ||
*/ | ||
type ErrorOptions = { | ||
cause?: unknown; | ||
}; | ||
declare abstract class OpenFeatureError extends Error { | ||
abstract code: ErrorCode; | ||
cause?: unknown; | ||
constructor(message?: string, options?: ErrorOptions); | ||
@@ -550,0 +558,0 @@ } |
{ | ||
"name": "@openfeature/core", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Shared OpenFeature JS components (server and web)", | ||
@@ -22,4 +22,4 @@ "main": "./dist/cjs/index.js", | ||
"type": "tsc --project ./tsconfig.json --declaration --emitDeclarationOnly", | ||
"build:esm": "esbuild src/index.ts --bundle --external:events --sourcemap --target=es2022 --format=esm --outfile=./dist/esm/index.js --analyze", | ||
"build:cjs": "esbuild src/index.ts --bundle --external:events --sourcemap --target=es2022 --format=cjs --outfile=./dist/cjs/index.js --analyze", | ||
"build:esm": "esbuild src/index.ts --bundle --external:events --sourcemap --target=es2015 --format=esm --outfile=./dist/esm/index.js --analyze", | ||
"build:cjs": "esbuild src/index.ts --bundle --external:events --sourcemap --target=es2015 --format=cjs --outfile=./dist/cjs/index.js --analyze", | ||
"build:rollup-types": "rollup -c ../../rollup.config.mjs", | ||
@@ -49,2 +49,2 @@ "build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:rollup-types", | ||
] | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
206902
3.97%2149
5.29%