@openfeature/js-sdk
Advanced tools
Comparing version
@@ -95,2 +95,3 @@ "use strict"; | ||
objectOrUndefined: () => objectOrUndefined, | ||
statusMatchesEvent: () => statusMatchesEvent, | ||
stringOrUndefined: () => stringOrUndefined | ||
@@ -217,11 +218,34 @@ }); | ||
// ../shared/src/provider/provider.ts | ||
var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => { | ||
ProviderStatus2["NOT_READY"] = "NOT_READY"; | ||
ProviderStatus2["READY"] = "READY"; | ||
ProviderStatus2["ERROR"] = "ERROR"; | ||
ProviderStatus2["STALE"] = "STALE"; | ||
return ProviderStatus2; | ||
})(ProviderStatus || {}); | ||
// ../shared/src/events/events.ts | ||
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => { | ||
ProviderEvents2["Ready"] = "PROVIDER_READY"; | ||
ProviderEvents2["Error"] = "PROVIDER_ERROR"; | ||
ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED"; | ||
ProviderEvents2["Stale"] = "PROVIDER_STALE"; | ||
return ProviderEvents2; | ||
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents3) => { | ||
ProviderEvents3["Ready"] = "PROVIDER_READY"; | ||
ProviderEvents3["Error"] = "PROVIDER_ERROR"; | ||
ProviderEvents3["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED"; | ||
ProviderEvents3["Stale"] = "PROVIDER_STALE"; | ||
return ProviderEvents3; | ||
})(ProviderEvents || {}); | ||
// ../shared/src/events/event-utils.ts | ||
var eventStatusMap = { | ||
["READY" /* READY */]: "PROVIDER_READY" /* Ready */, | ||
["ERROR" /* ERROR */]: "PROVIDER_ERROR" /* Error */, | ||
["STALE" /* STALE */]: "PROVIDER_STALE" /* Stale */, | ||
["NOT_READY" /* NOT_READY */]: void 0 | ||
}; | ||
var statusMatchesEvent = (event, status) => { | ||
return !status && event === "PROVIDER_READY" /* Ready */ || eventStatusMap[status] === event; | ||
}; | ||
// ../shared/src/events/open-feature-event-emitter.ts | ||
var import_events2 = __toESM(require("events")); | ||
// ../shared/src/logger/default-logger.ts | ||
@@ -281,3 +305,2 @@ var DefaultLogger = class { | ||
// ../shared/src/events/open-feature-event-emitter.ts | ||
var import_events = __toESM(require("events")); | ||
var GenericEventEmitter = class { | ||
@@ -288,3 +311,3 @@ constructor(globalLogger) { | ||
this._handlers = /* @__PURE__ */ new WeakMap(); | ||
this.eventEmitter = new import_events.default({ captureRejections: true }); | ||
this.eventEmitter = new import_events2.default({ captureRejections: true }); | ||
this.eventEmitter.on("error", (err) => { | ||
@@ -299,4 +322,4 @@ var _a; | ||
addHandler(eventType, handler) { | ||
const asyncHandler = (context) => __async(this, null, function* () { | ||
yield handler(context); | ||
const asyncHandler = (details) => __async(this, null, function* () { | ||
yield handler(details); | ||
}); | ||
@@ -337,10 +360,2 @@ this._handlers.set(handler, asyncHandler); | ||
// ../shared/src/provider/provider.ts | ||
var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => { | ||
ProviderStatus2["NOT_READY"] = "NOT_READY"; | ||
ProviderStatus2["READY"] = "READY"; | ||
ProviderStatus2["ERROR"] = "ERROR"; | ||
return ProviderStatus2; | ||
})(ProviderStatus || {}); | ||
// ../shared/src/transaction-context/no-op-transaction-context-propagator.ts | ||
@@ -378,3 +393,3 @@ var NoopTransactionContextPropagator = class { | ||
var OpenFeatureCommonAPI = class { | ||
constructor() { | ||
constructor(category) { | ||
this._hooks = []; | ||
@@ -388,2 +403,3 @@ this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR; | ||
this._clientEvents = /* @__PURE__ */ new Map(); | ||
this._runsOn = category; | ||
} | ||
@@ -415,3 +431,3 @@ addHooks(...hooks) { | ||
* The handlers are called in the order they have been added. | ||
* When changing the provider, the currently attached handlers will listen to the events of the new provider. | ||
* API (global) events run for all providers. | ||
* @param {ProviderEvents} eventType The provider event type to listen to | ||
@@ -421,2 +437,15 @@ * @param {EventHandler} handler The handler to run on occurrence of the event type | ||
addHandler(eventType, handler) { | ||
[.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._clientProviders].forEach((keyProviderTuple) => { | ||
var _a; | ||
const clientName = keyProviderTuple[0]; | ||
const provider = keyProviderTuple[1]; | ||
const shouldRunNow = statusMatchesEvent(eventType, keyProviderTuple[1].status); | ||
if (shouldRunNow) { | ||
try { | ||
handler({ clientName, providerName: provider.metadata.name }); | ||
} catch (err) { | ||
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
} | ||
} | ||
}); | ||
this._events.addHandler(eventType, handler); | ||
@@ -440,13 +469,34 @@ } | ||
} | ||
setProviderAndWait(clientOrProvider, providerOrUndefined) { | ||
return __async(this, null, function* () { | ||
yield this.setAwaitableProvider(clientOrProvider, providerOrUndefined); | ||
}); | ||
} | ||
setProvider(clientOrProvider, providerOrUndefined) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
const maybePromise = this.setAwaitableProvider(clientOrProvider, providerOrUndefined); | ||
if (maybePromise) { | ||
maybePromise.catch(() => { | ||
}); | ||
} | ||
return this; | ||
} | ||
setAwaitableProvider(clientOrProvider, providerOrUndefined) { | ||
var _a, _b, _c, _d, _e, _f; | ||
const clientName = stringOrUndefined(clientOrProvider); | ||
const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined); | ||
if (!provider) { | ||
return this; | ||
this._logger.debug("No provider defined, ignoring setProvider call"); | ||
return; | ||
} | ||
const oldProvider = this.getProviderForClient(clientName); | ||
const providerName = provider.metadata.name; | ||
if (oldProvider === provider) { | ||
return this; | ||
this._logger.debug("Provider is already set, ignoring setProvider call"); | ||
return; | ||
} | ||
if (!provider.runsOn) { | ||
this._logger.debug(`Provider '${provider.metadata.name}' has not defined its intended use.`); | ||
} else if (provider.runsOn !== this._runsOn) { | ||
throw new GeneralError(`Provider '${provider.metadata.name}' is intended for use on the ${provider.runsOn}.`); | ||
} | ||
const emitters = this.getAssociatedEventEmitters(clientName); | ||
@@ -456,24 +506,26 @@ if (typeof provider.initialize === "function" && provider.status === void 0) { | ||
activeLogger.warn( | ||
`Provider ${(_b = provider == null ? void 0 : provider.metadata) == null ? void 0 : _b.name} implements 'initialize' but not 'status'. Please implement 'status'.` | ||
`Provider ${providerName} implements 'initialize' but not 'status'. Please implement 'status'.` | ||
); | ||
} | ||
let initializationPromise = void 0; | ||
if ((provider == null ? void 0 : provider.status) === "NOT_READY" /* NOT_READY */ && typeof provider.initialize === "function") { | ||
(_e = (_d = (_c = provider.initialize) == null ? void 0 : _c.call(provider, this._context)) == null ? void 0 : _d.then(() => { | ||
initializationPromise = (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => { | ||
var _a2; | ||
this.getAssociatedEventEmitters(clientName).forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
}); | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
})) == null ? void 0 : _e.catch((error) => { | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
})) == null ? void 0 : _d.catch((error) => { | ||
var _a2; | ||
this.getAssociatedEventEmitters(clientName).forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message }); | ||
}); | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message }); | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message }); | ||
throw error; | ||
}); | ||
} else { | ||
emitters.forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
}); | ||
(_f = this._events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
(_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
} | ||
@@ -487,5 +539,5 @@ if (clientName) { | ||
if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) { | ||
(_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider); | ||
(_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider); | ||
} | ||
return this; | ||
return initializationPromise; | ||
} | ||
@@ -511,3 +563,3 @@ getProviderForClient(name) { | ||
return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () { | ||
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name })); | ||
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name, providerName: clientProvider.metadata.name })); | ||
})); | ||
@@ -541,5 +593,5 @@ } | ||
emitters.forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName })); | ||
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name })); | ||
}); | ||
this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName })); | ||
this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name })); | ||
}); | ||
@@ -643,3 +695,3 @@ return [eventType, handler]; | ||
constructor() { | ||
super(); | ||
super("server"); | ||
this._defaultProvider = NOOP_PROVIDER; | ||
@@ -704,6 +756,6 @@ } | ||
this.emitterAccessor().addHandler(eventType, handler); | ||
const providerReady = !this._provider.status || this._provider.status === "READY" /* READY */; | ||
if (eventType === "PROVIDER_READY" /* Ready */ && providerReady) { | ||
const shouldRunNow = statusMatchesEvent(eventType, this._provider.status); | ||
if (shouldRunNow) { | ||
try { | ||
handler({ clientName: this.metadata.name }); | ||
handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name }); | ||
} catch (err) { | ||
@@ -927,4 +979,5 @@ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
objectOrUndefined, | ||
statusMatchesEvent, | ||
stringOrUndefined | ||
}); | ||
//# sourceMappingURL=index.js.map |
@@ -158,11 +158,34 @@ var __defProp = Object.defineProperty; | ||
// ../shared/src/provider/provider.ts | ||
var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => { | ||
ProviderStatus2["NOT_READY"] = "NOT_READY"; | ||
ProviderStatus2["READY"] = "READY"; | ||
ProviderStatus2["ERROR"] = "ERROR"; | ||
ProviderStatus2["STALE"] = "STALE"; | ||
return ProviderStatus2; | ||
})(ProviderStatus || {}); | ||
// ../shared/src/events/events.ts | ||
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => { | ||
ProviderEvents2["Ready"] = "PROVIDER_READY"; | ||
ProviderEvents2["Error"] = "PROVIDER_ERROR"; | ||
ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED"; | ||
ProviderEvents2["Stale"] = "PROVIDER_STALE"; | ||
return ProviderEvents2; | ||
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents3) => { | ||
ProviderEvents3["Ready"] = "PROVIDER_READY"; | ||
ProviderEvents3["Error"] = "PROVIDER_ERROR"; | ||
ProviderEvents3["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED"; | ||
ProviderEvents3["Stale"] = "PROVIDER_STALE"; | ||
return ProviderEvents3; | ||
})(ProviderEvents || {}); | ||
// ../shared/src/events/event-utils.ts | ||
var eventStatusMap = { | ||
["READY" /* READY */]: "PROVIDER_READY" /* Ready */, | ||
["ERROR" /* ERROR */]: "PROVIDER_ERROR" /* Error */, | ||
["STALE" /* STALE */]: "PROVIDER_STALE" /* Stale */, | ||
["NOT_READY" /* NOT_READY */]: void 0 | ||
}; | ||
var statusMatchesEvent = (event, status) => { | ||
return !status && event === "PROVIDER_READY" /* Ready */ || eventStatusMap[status] === event; | ||
}; | ||
// ../shared/src/events/open-feature-event-emitter.ts | ||
import EventEmitter from "events"; | ||
// ../shared/src/logger/default-logger.ts | ||
@@ -222,3 +245,2 @@ var DefaultLogger = class { | ||
// ../shared/src/events/open-feature-event-emitter.ts | ||
import EventEmitter from "events"; | ||
var GenericEventEmitter = class { | ||
@@ -239,4 +261,4 @@ constructor(globalLogger) { | ||
addHandler(eventType, handler) { | ||
const asyncHandler = (context) => __async(this, null, function* () { | ||
yield handler(context); | ||
const asyncHandler = (details) => __async(this, null, function* () { | ||
yield handler(details); | ||
}); | ||
@@ -277,10 +299,2 @@ this._handlers.set(handler, asyncHandler); | ||
// ../shared/src/provider/provider.ts | ||
var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => { | ||
ProviderStatus2["NOT_READY"] = "NOT_READY"; | ||
ProviderStatus2["READY"] = "READY"; | ||
ProviderStatus2["ERROR"] = "ERROR"; | ||
return ProviderStatus2; | ||
})(ProviderStatus || {}); | ||
// ../shared/src/transaction-context/no-op-transaction-context-propagator.ts | ||
@@ -318,3 +332,3 @@ var NoopTransactionContextPropagator = class { | ||
var OpenFeatureCommonAPI = class { | ||
constructor() { | ||
constructor(category) { | ||
this._hooks = []; | ||
@@ -328,2 +342,3 @@ this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR; | ||
this._clientEvents = /* @__PURE__ */ new Map(); | ||
this._runsOn = category; | ||
} | ||
@@ -355,3 +370,3 @@ addHooks(...hooks) { | ||
* The handlers are called in the order they have been added. | ||
* When changing the provider, the currently attached handlers will listen to the events of the new provider. | ||
* API (global) events run for all providers. | ||
* @param {ProviderEvents} eventType The provider event type to listen to | ||
@@ -361,2 +376,15 @@ * @param {EventHandler} handler The handler to run on occurrence of the event type | ||
addHandler(eventType, handler) { | ||
[.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._clientProviders].forEach((keyProviderTuple) => { | ||
var _a; | ||
const clientName = keyProviderTuple[0]; | ||
const provider = keyProviderTuple[1]; | ||
const shouldRunNow = statusMatchesEvent(eventType, keyProviderTuple[1].status); | ||
if (shouldRunNow) { | ||
try { | ||
handler({ clientName, providerName: provider.metadata.name }); | ||
} catch (err) { | ||
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
} | ||
} | ||
}); | ||
this._events.addHandler(eventType, handler); | ||
@@ -380,13 +408,34 @@ } | ||
} | ||
setProviderAndWait(clientOrProvider, providerOrUndefined) { | ||
return __async(this, null, function* () { | ||
yield this.setAwaitableProvider(clientOrProvider, providerOrUndefined); | ||
}); | ||
} | ||
setProvider(clientOrProvider, providerOrUndefined) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
const maybePromise = this.setAwaitableProvider(clientOrProvider, providerOrUndefined); | ||
if (maybePromise) { | ||
maybePromise.catch(() => { | ||
}); | ||
} | ||
return this; | ||
} | ||
setAwaitableProvider(clientOrProvider, providerOrUndefined) { | ||
var _a, _b, _c, _d, _e, _f; | ||
const clientName = stringOrUndefined(clientOrProvider); | ||
const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined); | ||
if (!provider) { | ||
return this; | ||
this._logger.debug("No provider defined, ignoring setProvider call"); | ||
return; | ||
} | ||
const oldProvider = this.getProviderForClient(clientName); | ||
const providerName = provider.metadata.name; | ||
if (oldProvider === provider) { | ||
return this; | ||
this._logger.debug("Provider is already set, ignoring setProvider call"); | ||
return; | ||
} | ||
if (!provider.runsOn) { | ||
this._logger.debug(`Provider '${provider.metadata.name}' has not defined its intended use.`); | ||
} else if (provider.runsOn !== this._runsOn) { | ||
throw new GeneralError(`Provider '${provider.metadata.name}' is intended for use on the ${provider.runsOn}.`); | ||
} | ||
const emitters = this.getAssociatedEventEmitters(clientName); | ||
@@ -396,24 +445,26 @@ if (typeof provider.initialize === "function" && provider.status === void 0) { | ||
activeLogger.warn( | ||
`Provider ${(_b = provider == null ? void 0 : provider.metadata) == null ? void 0 : _b.name} implements 'initialize' but not 'status'. Please implement 'status'.` | ||
`Provider ${providerName} implements 'initialize' but not 'status'. Please implement 'status'.` | ||
); | ||
} | ||
let initializationPromise = void 0; | ||
if ((provider == null ? void 0 : provider.status) === "NOT_READY" /* NOT_READY */ && typeof provider.initialize === "function") { | ||
(_e = (_d = (_c = provider.initialize) == null ? void 0 : _c.call(provider, this._context)) == null ? void 0 : _d.then(() => { | ||
initializationPromise = (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => { | ||
var _a2; | ||
this.getAssociatedEventEmitters(clientName).forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
}); | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
})) == null ? void 0 : _e.catch((error) => { | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
})) == null ? void 0 : _d.catch((error) => { | ||
var _a2; | ||
this.getAssociatedEventEmitters(clientName).forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message }); | ||
}); | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, message: error.message }); | ||
(_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message }); | ||
throw error; | ||
}); | ||
} else { | ||
emitters.forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
}); | ||
(_f = this._events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */, { clientName }); | ||
(_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName, providerName }); | ||
} | ||
@@ -427,5 +478,5 @@ if (clientName) { | ||
if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) { | ||
(_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider); | ||
(_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider); | ||
} | ||
return this; | ||
return initializationPromise; | ||
} | ||
@@ -451,3 +502,3 @@ getProviderForClient(name) { | ||
return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () { | ||
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name })); | ||
newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name, providerName: clientProvider.metadata.name })); | ||
})); | ||
@@ -481,5 +532,5 @@ } | ||
emitters.forEach((emitter) => { | ||
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName })); | ||
emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name })); | ||
}); | ||
this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName })); | ||
this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name })); | ||
}); | ||
@@ -583,3 +634,3 @@ return [eventType, handler]; | ||
constructor() { | ||
super(); | ||
super("server"); | ||
this._defaultProvider = NOOP_PROVIDER; | ||
@@ -644,6 +695,6 @@ } | ||
this.emitterAccessor().addHandler(eventType, handler); | ||
const providerReady = !this._provider.status || this._provider.status === "READY" /* READY */; | ||
if (eventType === "PROVIDER_READY" /* Ready */ && providerReady) { | ||
const shouldRunNow = statusMatchesEvent(eventType, this._provider.status); | ||
if (shouldRunNow) { | ||
try { | ||
handler({ clientName: this.metadata.name }); | ||
handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name }); | ||
} catch (err) { | ||
@@ -866,4 +917,5 @@ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err); | ||
objectOrUndefined, | ||
statusMatchesEvent, | ||
stringOrUndefined | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -0,1 +1,131 @@ | ||
type FlagValueType = 'boolean' | 'string' | 'number' | 'object'; | ||
type PrimitiveValue = null | boolean | string | number; | ||
type JsonObject = { | ||
[key: string]: JsonValue; | ||
}; | ||
type JsonArray = JsonValue[]; | ||
/** | ||
* Represents a JSON node value. | ||
*/ | ||
type JsonValue = PrimitiveValue | JsonObject | JsonArray; | ||
/** | ||
* Represents a JSON node value, or Date. | ||
*/ | ||
type FlagValue = boolean | string | number | JsonValue; | ||
type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>); | ||
/** | ||
* A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number. | ||
* | ||
* This structure is populated by a provider for use by an Application Author (via the Evaluation API) or an Application Integrator (via hooks). | ||
*/ | ||
type FlagMetadata = Record<string, string | number | boolean>; | ||
type ResolutionDetails<U> = { | ||
value: U; | ||
variant?: string; | ||
flagMetadata?: FlagMetadata; | ||
reason?: ResolutionReason; | ||
errorCode?: ErrorCode; | ||
errorMessage?: string; | ||
}; | ||
type EvaluationDetails<T extends FlagValue> = { | ||
flagKey: string; | ||
flagMetadata: Readonly<FlagMetadata>; | ||
} & ResolutionDetails<T>; | ||
declare const StandardResolutionReasons: { | ||
/** | ||
* The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting. | ||
*/ | ||
readonly TARGETING_MATCH: "TARGETING_MATCH"; | ||
/** | ||
* The resolved value was the result of pseudorandom assignment. | ||
*/ | ||
readonly SPLIT: "SPLIT"; | ||
/** | ||
* The resolved value was the result of the flag being disabled in the management system. | ||
*/ | ||
readonly DISABLED: "DISABLED"; | ||
/** | ||
* The resolved value was configured statically, or otherwise fell back to a pre-configured value. | ||
*/ | ||
readonly DEFAULT: "DEFAULT"; | ||
/** | ||
* The reason for the resolved value could not be determined. | ||
*/ | ||
readonly UNKNOWN: "UNKNOWN"; | ||
/** | ||
* The resolved value is static (no dynamic evaluation). | ||
*/ | ||
readonly STATIC: "STATIC"; | ||
/** | ||
* The resolved value was retrieved from cache. | ||
*/ | ||
readonly CACHED: "CACHED"; | ||
/** | ||
* The resolved value was the result of an error. | ||
* | ||
* Note: The `errorCode` and `errorMessage` fields may contain additional details of this error. | ||
*/ | ||
readonly ERROR: "ERROR"; | ||
}; | ||
declare enum ErrorCode { | ||
/** | ||
* The value was resolved before the provider was ready. | ||
*/ | ||
PROVIDER_NOT_READY = "PROVIDER_NOT_READY", | ||
/** | ||
* The flag could not be found. | ||
*/ | ||
FLAG_NOT_FOUND = "FLAG_NOT_FOUND", | ||
/** | ||
* An error was encountered parsing data, such as a flag configuration. | ||
*/ | ||
PARSE_ERROR = "PARSE_ERROR", | ||
/** | ||
* The type of the flag value does not match the expected type. | ||
*/ | ||
TYPE_MISMATCH = "TYPE_MISMATCH", | ||
/** | ||
* The provider requires a targeting key and one was not provided in the evaluation context. | ||
*/ | ||
TARGETING_KEY_MISSING = "TARGETING_KEY_MISSING", | ||
/** | ||
* The evaluation context does not meet provider requirements. | ||
*/ | ||
INVALID_CONTEXT = "INVALID_CONTEXT", | ||
/** | ||
* An error with an unspecified code. | ||
*/ | ||
GENERAL = "GENERAL" | ||
} | ||
type EvaluationContextValue = PrimitiveValue | Date | { | ||
[key: string]: EvaluationContextValue; | ||
} | EvaluationContextValue[]; | ||
/** | ||
* A container for arbitrary contextual data that can be used as a basis for dynamic evaluation | ||
*/ | ||
type EvaluationContext = { | ||
/** | ||
* A string uniquely identifying the subject (end-user, or client service) of a flag evaluation. | ||
* Providers may require this field for fractional flag evaluation, rules, or overrides targeting specific users. | ||
* Such providers may behave unpredictably if a targeting key is not specified at flag resolution. | ||
*/ | ||
targetingKey?: string; | ||
} & Record<string, EvaluationContextValue>; | ||
interface ManageContext<T> { | ||
/** | ||
* Access the evaluation context set on the receiver. | ||
* @returns {EvaluationContext} Evaluation context | ||
*/ | ||
getContext(): EvaluationContext; | ||
/** | ||
* Sets evaluation context that will be used during flag evaluations | ||
* on this receiver. | ||
* @template T The type of the receiver | ||
* @param {EvaluationContext} context Evaluation context | ||
* @returns {T} The receiver (this object) | ||
*/ | ||
setContext(context: EvaluationContext): T; | ||
} | ||
declare enum ProviderEvents { | ||
@@ -20,2 +150,11 @@ /** | ||
/** | ||
* Returns true if the provider's status corresponds to the event. | ||
* If the provider's status is not defined, it matches READY. | ||
* @param {ProviderEvents} event event to match | ||
* @param {ProviderStatus} status status of provider | ||
* @returns {boolean} boolean indicating if the provider status corresponds to the event. | ||
*/ | ||
declare const statusMatchesEvent: (event: ProviderEvents, status?: ProviderStatus) => boolean; | ||
type EventMetadata = { | ||
@@ -25,2 +164,3 @@ [key: string]: string | boolean | number; | ||
type CommonEventDetails = { | ||
providerName: string; | ||
clientName?: string; | ||
@@ -141,133 +281,8 @@ }; | ||
type FlagValueType = 'boolean' | 'string' | 'number' | 'object'; | ||
type PrimitiveValue = null | boolean | string | number; | ||
type JsonObject = { | ||
[key: string]: JsonValue; | ||
}; | ||
type JsonArray = JsonValue[]; | ||
/** | ||
* Represents a JSON node value. | ||
* Defines where the library is intended to be run. | ||
*/ | ||
type JsonValue = PrimitiveValue | JsonObject | JsonArray; | ||
/** | ||
* Represents a JSON node value, or Date. | ||
*/ | ||
type FlagValue = boolean | string | number | JsonValue; | ||
type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>); | ||
/** | ||
* A structure which supports definition of arbitrary properties, with keys of type string, and values of type boolean, string, or number. | ||
* | ||
* This structure is populated by a provider for use by an Application Author (via the Evaluation API) or an Application Integrator (via hooks). | ||
*/ | ||
type FlagMetadata = Record<string, string | number | boolean>; | ||
type ResolutionDetails<U> = { | ||
value: U; | ||
variant?: string; | ||
flagMetadata?: FlagMetadata; | ||
reason?: ResolutionReason; | ||
errorCode?: ErrorCode; | ||
errorMessage?: string; | ||
}; | ||
type EvaluationDetails<T extends FlagValue> = { | ||
flagKey: string; | ||
flagMetadata: Readonly<FlagMetadata>; | ||
} & ResolutionDetails<T>; | ||
declare const StandardResolutionReasons: { | ||
/** | ||
* The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting. | ||
*/ | ||
readonly TARGETING_MATCH: "TARGETING_MATCH"; | ||
/** | ||
* The resolved value was the result of pseudorandom assignment. | ||
*/ | ||
readonly SPLIT: "SPLIT"; | ||
/** | ||
* The resolved value was the result of the flag being disabled in the management system. | ||
*/ | ||
readonly DISABLED: "DISABLED"; | ||
/** | ||
* The resolved value was configured statically, or otherwise fell back to a pre-configured value. | ||
*/ | ||
readonly DEFAULT: "DEFAULT"; | ||
/** | ||
* The reason for the resolved value could not be determined. | ||
*/ | ||
readonly UNKNOWN: "UNKNOWN"; | ||
/** | ||
* The resolved value is static (no dynamic evaluation). | ||
*/ | ||
readonly STATIC: "STATIC"; | ||
/** | ||
* The resolved value was retrieved from cache. | ||
*/ | ||
readonly CACHED: "CACHED"; | ||
/** | ||
* The resolved value was the result of an error. | ||
* | ||
* Note: The `errorCode` and `errorMessage` fields may contain additional details of this error. | ||
*/ | ||
readonly ERROR: "ERROR"; | ||
}; | ||
declare enum ErrorCode { | ||
/** | ||
* The value was resolved before the provider was ready. | ||
*/ | ||
PROVIDER_NOT_READY = "PROVIDER_NOT_READY", | ||
/** | ||
* The flag could not be found. | ||
*/ | ||
FLAG_NOT_FOUND = "FLAG_NOT_FOUND", | ||
/** | ||
* An error was encountered parsing data, such as a flag configuration. | ||
*/ | ||
PARSE_ERROR = "PARSE_ERROR", | ||
/** | ||
* The type of the flag value does not match the expected type. | ||
*/ | ||
TYPE_MISMATCH = "TYPE_MISMATCH", | ||
/** | ||
* The provider requires a targeting key and one was not provided in the evaluation context. | ||
*/ | ||
TARGETING_KEY_MISSING = "TARGETING_KEY_MISSING", | ||
/** | ||
* The evaluation context does not meet provider requirements. | ||
*/ | ||
INVALID_CONTEXT = "INVALID_CONTEXT", | ||
/** | ||
* An error with an unspecified code. | ||
*/ | ||
GENERAL = "GENERAL" | ||
} | ||
type Paradigm = 'server' | 'client'; | ||
type EvaluationContextValue = PrimitiveValue | Date | { | ||
[key: string]: EvaluationContextValue; | ||
} | EvaluationContextValue[]; | ||
/** | ||
* A container for arbitrary contextual data that can be used as a basis for dynamic evaluation | ||
*/ | ||
type EvaluationContext = { | ||
/** | ||
* A string uniquely identifying the subject (end-user, or client service) of a flag evaluation. | ||
* Providers may require this field for fractional flag evaluation, rules, or overrides targeting specific users. | ||
* Such providers may behave unpredictably if a targeting key is not specified at flag resolution. | ||
*/ | ||
targetingKey?: string; | ||
} & Record<string, EvaluationContextValue>; | ||
interface ManageContext<T> { | ||
/** | ||
* Access the evaluation context set on the receiver. | ||
* @returns {EvaluationContext} Evaluation context | ||
*/ | ||
getContext(): EvaluationContext; | ||
/** | ||
* Sets evaluation context that will be used during flag evaluations | ||
* on this receiver. | ||
* @template T The type of the receiver | ||
* @param {EvaluationContext} context Evaluation context | ||
* @returns {T} The receiver (this object) | ||
*/ | ||
setContext(context: EvaluationContext): T; | ||
} | ||
/** | ||
* The state of the provider. | ||
@@ -287,3 +302,7 @@ */ | ||
*/ | ||
ERROR = "ERROR" | ||
ERROR = "ERROR", | ||
/** | ||
* The provider's cached state is no longer valid and may not be up-to-date with the source of truth. | ||
*/ | ||
STALE = "STALE" | ||
} | ||
@@ -299,2 +318,7 @@ /** | ||
/** | ||
* Represents where the provider is intended to be run. If defined, | ||
* the SDK will enforce that the defined paradigm at runtime. | ||
*/ | ||
readonly runsOn?: Paradigm; | ||
/** | ||
* Returns a representation of the current readiness of the provider. | ||
@@ -527,2 +551,4 @@ * If the provider needs to be initialized, it should return {@link ProviderStatus.READY}. | ||
protected _clientEvents: Map<string | undefined, InternalEventEmitter>; | ||
protected _runsOn: Paradigm; | ||
constructor(category: Paradigm); | ||
addHooks(...hooks: Hook<FlagValue>[]): this; | ||
@@ -540,3 +566,3 @@ getHooks(): Hook<FlagValue>[]; | ||
* The handlers are called in the order they have been added. | ||
* When changing the provider, the currently attached handlers will listen to the events of the new provider. | ||
* API (global) events run for all providers. | ||
* @param {ProviderEvents} eventType The provider event type to listen to | ||
@@ -559,2 +585,23 @@ * @param {EventHandler} handler The handler to run on occurrence of the event type | ||
/** | ||
* Sets the default provider for flag evaluations and returns a promise that resolves when the provider is ready. | ||
* This provider will be used by unnamed clients and named clients to which no provider is bound. | ||
* Setting a provider supersedes the current provider used in new and existing clients without a name. | ||
* @template P | ||
* @param {P} provider The provider responsible for flag evaluations. | ||
* @returns {Promise<void>} | ||
* @throws Uncaught exceptions thrown by the provider during initialization. | ||
*/ | ||
setProviderAndWait(provider: P): Promise<void>; | ||
/** | ||
* Sets the provider that OpenFeature will use for flag evaluations of providers with the given name. | ||
* A promise is returned that resolves when the provider is ready. | ||
* Setting a provider supersedes the current provider used in new and existing clients with that name. | ||
* @template P | ||
* @param {string} clientName The name to identify the client | ||
* @param {P} provider The provider responsible for flag evaluations. | ||
* @returns {Promise<void>} | ||
* @throws Uncaught exceptions thrown by the provider during initialization. | ||
*/ | ||
setProviderAndWait(clientName: string, provider: P): Promise<void>; | ||
/** | ||
* Sets the default provider for flag evaluations. | ||
@@ -565,3 +612,3 @@ * This provider will be used by unnamed clients and named clients to which no provider is bound. | ||
* @param {P} provider The provider responsible for flag evaluations. | ||
* @returns {OpenFeatureCommonAPI} OpenFeature API | ||
* @returns {this} OpenFeature API | ||
*/ | ||
@@ -578,2 +625,3 @@ setProvider(provider: P): this; | ||
setProvider(clientName: string, provider: P): this; | ||
private setAwaitableProvider; | ||
protected getProviderForClient(name?: string): P; | ||
@@ -827,2 +875,2 @@ protected buildAndCacheEventEmitterForClient(name?: string): InternalEventEmitter; | ||
export { BeforeHookContext, Client, ClientMetadata, CommonEventDetails, CommonProvider, ConfigChangeEvent, DefaultLogger, ErrorCode, ErrorEvent, EvaluationContext, EvaluationContextValue, EvaluationDetails, EvaluationLifeCycle, EventContext, EventDetails, EventHandler, EventMetadata, Eventing, Features, FlagEvaluationOptions, FlagMetadata, FlagNotFoundError, FlagValue, FlagValueType, GeneralError, Hook, HookContext, HookHints, InternalEventEmitter, InvalidContextError, JsonArray, JsonObject, JsonValue, LOG_LEVELS, Logger, ManageContext, ManageLogger, ManageTransactionContextPropagator, Metadata, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureCommonAPI, OpenFeatureError, OpenFeatureEventEmitter, ParseError, PrimitiveValue, Provider, ProviderEvents, ProviderMetadata, ProviderStatus, ReadyEvent, ResolutionDetails, ResolutionReason, SafeLogger, StaleEvent, StandardResolutionReasons, TargetingKeyMissingError, TransactionContext, TransactionContextPropagator, TypeMismatchError, isObject, isString, objectOrUndefined, stringOrUndefined }; | ||
export { BeforeHookContext, Client, ClientMetadata, CommonEventDetails, CommonProvider, ConfigChangeEvent, DefaultLogger, ErrorCode, ErrorEvent, EvaluationContext, EvaluationContextValue, EvaluationDetails, EvaluationLifeCycle, EventContext, EventDetails, EventHandler, EventMetadata, Eventing, Features, FlagEvaluationOptions, FlagMetadata, FlagNotFoundError, FlagValue, FlagValueType, GeneralError, Hook, HookContext, HookHints, InternalEventEmitter, InvalidContextError, JsonArray, JsonObject, JsonValue, LOG_LEVELS, Logger, ManageContext, ManageLogger, ManageTransactionContextPropagator, Metadata, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureCommonAPI, OpenFeatureError, OpenFeatureEventEmitter, Paradigm, ParseError, PrimitiveValue, Provider, ProviderEvents, ProviderMetadata, ProviderStatus, ReadyEvent, ResolutionDetails, ResolutionReason, SafeLogger, StaleEvent, StandardResolutionReasons, TargetingKeyMissingError, TransactionContext, TransactionContextPropagator, TypeMismatchError, isObject, isString, objectOrUndefined, statusMatchesEvent, stringOrUndefined }; |
{ | ||
"name": "@openfeature/js-sdk", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"description": "OpenFeature SDK for JavaScript", | ||
@@ -5,0 +5,0 @@ "main": "./dist/cjs/index.js", |
@@ -6,8 +6,7 @@ <!-- markdownlint-disable MD033 --> | ||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/white/openfeature-horizontal-white.svg" /> | ||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/black/openfeature-horizontal-black.svg" /> | ||
<img align="center" alt="OpenFeature Logo"> | ||
<img align="center" alt="OpenFeature Logo" src="https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/black/openfeature-horizontal-black.svg" /> | ||
</picture> | ||
</p> | ||
<h2 align="center">OpenFeature JS Server-side SDK</h2> | ||
<h2 align="center">OpenFeature Node.js SDK</h2> | ||
@@ -17,8 +16,8 @@ <!-- x-hide-in-docs-end --> | ||
<p align="center" class="github-badges"> | ||
<a href="https://github.com/open-feature/spec/tree/v0.6.0"> | ||
<img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.6.0&color=yellow&style=for-the-badge" /> | ||
<a href="https://github.com/open-feature/spec/tree/v0.7.0"> | ||
<img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.7.0&color=yellow&style=for-the-badge" /> | ||
</a> | ||
<!-- x-release-please-start-version --> | ||
<a href="https://github.com/open-feature/js-sdk/releases/tag/js-sdk-v1.4.2"> | ||
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.4.2&color=blue&style=for-the-badge" /> | ||
<a href="https://github.com/open-feature/js-sdk/releases/tag/js-sdk-v1.5.0"> | ||
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.5.0&color=blue&style=for-the-badge" /> | ||
</a> | ||
@@ -25,0 +24,0 @@ <!-- x-release-please-end --> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
263022
7.6%2661
5.85%305
-0.33%