@openfeature/core
Advanced tools
Comparing version 1.2.0 to 1.3.0
"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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
206902
2149