@openfeature/web-sdk
Advanced tools
Comparing version
"use strict"; | ||
var __create = Object.create; | ||
var __defProp = Object.defineProperty; | ||
@@ -8,2 +9,3 @@ var __defProps = Object.defineProperties; | ||
var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
var __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
@@ -24,2 +26,5 @@ var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
var __commonJS = (cb, mod) => function __require() { | ||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; | ||
}; | ||
var __export = (target, all) => { | ||
@@ -37,2 +42,10 @@ for (var name in all) | ||
}; | ||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
// If the importer is in node compatibility mode or this is not an ESM | ||
// file that has been converted to a CommonJS file using a Babel- | ||
// compatible transform (i.e. "__esModule" has not been set), then set | ||
// "default" to the CommonJS "module.exports" for node compatibility. | ||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
mod | ||
)); | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
@@ -60,2 +73,374 @@ var __async = (__this, __arguments, generator) => { | ||
// ../../node_modules/events/events.js | ||
var require_events = __commonJS({ | ||
"../../node_modules/events/events.js"(exports, module2) { | ||
"use strict"; | ||
var R = typeof Reflect === "object" ? Reflect : null; | ||
var ReflectApply = R && typeof R.apply === "function" ? R.apply : function ReflectApply2(target, receiver, args) { | ||
return Function.prototype.apply.call(target, receiver, args); | ||
}; | ||
var ReflectOwnKeys; | ||
if (R && typeof R.ownKeys === "function") { | ||
ReflectOwnKeys = R.ownKeys; | ||
} else if (Object.getOwnPropertySymbols) { | ||
ReflectOwnKeys = function ReflectOwnKeys2(target) { | ||
return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)); | ||
}; | ||
} else { | ||
ReflectOwnKeys = function ReflectOwnKeys2(target) { | ||
return Object.getOwnPropertyNames(target); | ||
}; | ||
} | ||
function ProcessEmitWarning(warning) { | ||
if (console && console.warn) | ||
console.warn(warning); | ||
} | ||
var NumberIsNaN = Number.isNaN || function NumberIsNaN2(value) { | ||
return value !== value; | ||
}; | ||
function EventEmitter2() { | ||
EventEmitter2.init.call(this); | ||
} | ||
module2.exports = EventEmitter2; | ||
module2.exports.once = once; | ||
EventEmitter2.EventEmitter = EventEmitter2; | ||
EventEmitter2.prototype._events = void 0; | ||
EventEmitter2.prototype._eventsCount = 0; | ||
EventEmitter2.prototype._maxListeners = void 0; | ||
var defaultMaxListeners = 10; | ||
function checkListener(listener) { | ||
if (typeof listener !== "function") { | ||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); | ||
} | ||
} | ||
Object.defineProperty(EventEmitter2, "defaultMaxListeners", { | ||
enumerable: true, | ||
get: function() { | ||
return defaultMaxListeners; | ||
}, | ||
set: function(arg) { | ||
if (typeof arg !== "number" || arg < 0 || NumberIsNaN(arg)) { | ||
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + "."); | ||
} | ||
defaultMaxListeners = arg; | ||
} | ||
}); | ||
EventEmitter2.init = function() { | ||
if (this._events === void 0 || this._events === Object.getPrototypeOf(this)._events) { | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
this._eventsCount = 0; | ||
} | ||
this._maxListeners = this._maxListeners || void 0; | ||
}; | ||
EventEmitter2.prototype.setMaxListeners = function setMaxListeners(n) { | ||
if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) { | ||
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + "."); | ||
} | ||
this._maxListeners = n; | ||
return this; | ||
}; | ||
function _getMaxListeners(that) { | ||
if (that._maxListeners === void 0) | ||
return EventEmitter2.defaultMaxListeners; | ||
return that._maxListeners; | ||
} | ||
EventEmitter2.prototype.getMaxListeners = function getMaxListeners() { | ||
return _getMaxListeners(this); | ||
}; | ||
EventEmitter2.prototype.emit = function emit(type) { | ||
var args = []; | ||
for (var i = 1; i < arguments.length; i++) | ||
args.push(arguments[i]); | ||
var doError = type === "error"; | ||
var events = this._events; | ||
if (events !== void 0) | ||
doError = doError && events.error === void 0; | ||
else if (!doError) | ||
return false; | ||
if (doError) { | ||
var er; | ||
if (args.length > 0) | ||
er = args[0]; | ||
if (er instanceof Error) { | ||
throw er; | ||
} | ||
var err = new Error("Unhandled error." + (er ? " (" + er.message + ")" : "")); | ||
err.context = er; | ||
throw err; | ||
} | ||
var handler = events[type]; | ||
if (handler === void 0) | ||
return false; | ||
if (typeof handler === "function") { | ||
ReflectApply(handler, this, args); | ||
} else { | ||
var len = handler.length; | ||
var listeners = arrayClone(handler, len); | ||
for (var i = 0; i < len; ++i) | ||
ReflectApply(listeners[i], this, args); | ||
} | ||
return true; | ||
}; | ||
function _addListener(target, type, listener, prepend) { | ||
var m; | ||
var events; | ||
var existing; | ||
checkListener(listener); | ||
events = target._events; | ||
if (events === void 0) { | ||
events = target._events = /* @__PURE__ */ Object.create(null); | ||
target._eventsCount = 0; | ||
} else { | ||
if (events.newListener !== void 0) { | ||
target.emit( | ||
"newListener", | ||
type, | ||
listener.listener ? listener.listener : listener | ||
); | ||
events = target._events; | ||
} | ||
existing = events[type]; | ||
} | ||
if (existing === void 0) { | ||
existing = events[type] = listener; | ||
++target._eventsCount; | ||
} else { | ||
if (typeof existing === "function") { | ||
existing = events[type] = prepend ? [listener, existing] : [existing, listener]; | ||
} else if (prepend) { | ||
existing.unshift(listener); | ||
} else { | ||
existing.push(listener); | ||
} | ||
m = _getMaxListeners(target); | ||
if (m > 0 && existing.length > m && !existing.warned) { | ||
existing.warned = true; | ||
var w = new Error("Possible EventEmitter memory leak detected. " + existing.length + " " + String(type) + " listeners added. Use emitter.setMaxListeners() to increase limit"); | ||
w.name = "MaxListenersExceededWarning"; | ||
w.emitter = target; | ||
w.type = type; | ||
w.count = existing.length; | ||
ProcessEmitWarning(w); | ||
} | ||
} | ||
return target; | ||
} | ||
EventEmitter2.prototype.addListener = function addListener(type, listener) { | ||
return _addListener(this, type, listener, false); | ||
}; | ||
EventEmitter2.prototype.on = EventEmitter2.prototype.addListener; | ||
EventEmitter2.prototype.prependListener = function prependListener(type, listener) { | ||
return _addListener(this, type, listener, true); | ||
}; | ||
function onceWrapper() { | ||
if (!this.fired) { | ||
this.target.removeListener(this.type, this.wrapFn); | ||
this.fired = true; | ||
if (arguments.length === 0) | ||
return this.listener.call(this.target); | ||
return this.listener.apply(this.target, arguments); | ||
} | ||
} | ||
function _onceWrap(target, type, listener) { | ||
var state = { fired: false, wrapFn: void 0, target, type, listener }; | ||
var wrapped = onceWrapper.bind(state); | ||
wrapped.listener = listener; | ||
state.wrapFn = wrapped; | ||
return wrapped; | ||
} | ||
EventEmitter2.prototype.once = function once2(type, listener) { | ||
checkListener(listener); | ||
this.on(type, _onceWrap(this, type, listener)); | ||
return this; | ||
}; | ||
EventEmitter2.prototype.prependOnceListener = function prependOnceListener(type, listener) { | ||
checkListener(listener); | ||
this.prependListener(type, _onceWrap(this, type, listener)); | ||
return this; | ||
}; | ||
EventEmitter2.prototype.removeListener = function removeListener(type, listener) { | ||
var list, events, position, i, originalListener; | ||
checkListener(listener); | ||
events = this._events; | ||
if (events === void 0) | ||
return this; | ||
list = events[type]; | ||
if (list === void 0) | ||
return this; | ||
if (list === listener || list.listener === listener) { | ||
if (--this._eventsCount === 0) | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
else { | ||
delete events[type]; | ||
if (events.removeListener) | ||
this.emit("removeListener", type, list.listener || listener); | ||
} | ||
} else if (typeof list !== "function") { | ||
position = -1; | ||
for (i = list.length - 1; i >= 0; i--) { | ||
if (list[i] === listener || list[i].listener === listener) { | ||
originalListener = list[i].listener; | ||
position = i; | ||
break; | ||
} | ||
} | ||
if (position < 0) | ||
return this; | ||
if (position === 0) | ||
list.shift(); | ||
else { | ||
spliceOne(list, position); | ||
} | ||
if (list.length === 1) | ||
events[type] = list[0]; | ||
if (events.removeListener !== void 0) | ||
this.emit("removeListener", type, originalListener || listener); | ||
} | ||
return this; | ||
}; | ||
EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener; | ||
EventEmitter2.prototype.removeAllListeners = function removeAllListeners(type) { | ||
var listeners, events, i; | ||
events = this._events; | ||
if (events === void 0) | ||
return this; | ||
if (events.removeListener === void 0) { | ||
if (arguments.length === 0) { | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
this._eventsCount = 0; | ||
} else if (events[type] !== void 0) { | ||
if (--this._eventsCount === 0) | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
else | ||
delete events[type]; | ||
} | ||
return this; | ||
} | ||
if (arguments.length === 0) { | ||
var keys = Object.keys(events); | ||
var key; | ||
for (i = 0; i < keys.length; ++i) { | ||
key = keys[i]; | ||
if (key === "removeListener") | ||
continue; | ||
this.removeAllListeners(key); | ||
} | ||
this.removeAllListeners("removeListener"); | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
this._eventsCount = 0; | ||
return this; | ||
} | ||
listeners = events[type]; | ||
if (typeof listeners === "function") { | ||
this.removeListener(type, listeners); | ||
} else if (listeners !== void 0) { | ||
for (i = listeners.length - 1; i >= 0; i--) { | ||
this.removeListener(type, listeners[i]); | ||
} | ||
} | ||
return this; | ||
}; | ||
function _listeners(target, type, unwrap) { | ||
var events = target._events; | ||
if (events === void 0) | ||
return []; | ||
var evlistener = events[type]; | ||
if (evlistener === void 0) | ||
return []; | ||
if (typeof evlistener === "function") | ||
return unwrap ? [evlistener.listener || evlistener] : [evlistener]; | ||
return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); | ||
} | ||
EventEmitter2.prototype.listeners = function listeners(type) { | ||
return _listeners(this, type, true); | ||
}; | ||
EventEmitter2.prototype.rawListeners = function rawListeners(type) { | ||
return _listeners(this, type, false); | ||
}; | ||
EventEmitter2.listenerCount = function(emitter, type) { | ||
if (typeof emitter.listenerCount === "function") { | ||
return emitter.listenerCount(type); | ||
} else { | ||
return listenerCount.call(emitter, type); | ||
} | ||
}; | ||
EventEmitter2.prototype.listenerCount = listenerCount; | ||
function listenerCount(type) { | ||
var events = this._events; | ||
if (events !== void 0) { | ||
var evlistener = events[type]; | ||
if (typeof evlistener === "function") { | ||
return 1; | ||
} else if (evlistener !== void 0) { | ||
return evlistener.length; | ||
} | ||
} | ||
return 0; | ||
} | ||
EventEmitter2.prototype.eventNames = function eventNames() { | ||
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; | ||
}; | ||
function arrayClone(arr, n) { | ||
var copy = new Array(n); | ||
for (var i = 0; i < n; ++i) | ||
copy[i] = arr[i]; | ||
return copy; | ||
} | ||
function spliceOne(list, index) { | ||
for (; index + 1 < list.length; index++) | ||
list[index] = list[index + 1]; | ||
list.pop(); | ||
} | ||
function unwrapListeners(arr) { | ||
var ret = new Array(arr.length); | ||
for (var i = 0; i < ret.length; ++i) { | ||
ret[i] = arr[i].listener || arr[i]; | ||
} | ||
return ret; | ||
} | ||
function once(emitter, name) { | ||
return new Promise(function(resolve, reject) { | ||
function errorListener(err) { | ||
emitter.removeListener(name, resolver); | ||
reject(err); | ||
} | ||
function resolver() { | ||
if (typeof emitter.removeListener === "function") { | ||
emitter.removeListener("error", errorListener); | ||
} | ||
resolve([].slice.call(arguments)); | ||
} | ||
; | ||
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); | ||
if (name !== "error") { | ||
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); | ||
} | ||
}); | ||
} | ||
function addErrorHandlerIfEventEmitter(emitter, handler, flags) { | ||
if (typeof emitter.on === "function") { | ||
eventTargetAgnosticAddListener(emitter, "error", handler, flags); | ||
} | ||
} | ||
function eventTargetAgnosticAddListener(emitter, name, listener, flags) { | ||
if (typeof emitter.on === "function") { | ||
if (flags.once) { | ||
emitter.once(name, listener); | ||
} else { | ||
emitter.on(name, listener); | ||
} | ||
} else if (typeof emitter.addEventListener === "function") { | ||
emitter.addEventListener(name, function wrapListener(arg) { | ||
if (flags.once) { | ||
emitter.removeEventListener(name, wrapListener); | ||
} | ||
listener(arg); | ||
}); | ||
} else { | ||
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); | ||
} | ||
} | ||
} | ||
}); | ||
// src/index.ts | ||
@@ -312,2 +697,5 @@ var src_exports = {}; | ||
// src/open-feature.ts | ||
var import_events = __toESM(require_events()); | ||
// src/no-op-provider.ts | ||
@@ -349,2 +737,4 @@ var REASON_NO_OP = "No-op"; | ||
super(); | ||
this._apiEvents = new import_events.EventEmitter(); | ||
this._providerReady = false; | ||
this._hooks = []; | ||
@@ -400,8 +790,25 @@ this._provider = NOOP_PROVIDER; | ||
setProvider(provider) { | ||
var _a; | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if (this._provider !== provider) { | ||
const oldProvider = this._provider; | ||
this._provider = provider; | ||
window.dispatchEvent(new CustomEvent("providerChanged" /* ProviderChanged */)); | ||
(_a = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _a.call(oldProvider); | ||
this._providerReady = false; | ||
if (!this._provider.events) { | ||
this._provider.events = new import_events.EventEmitter(); | ||
} | ||
if (typeof ((_a = this._provider) == null ? void 0 : _a.initialize) === "function") { | ||
(_e = (_d = (_c = (_b = this._provider).initialize) == null ? void 0 : _c.call(_b, this._context)) == null ? void 0 : _d.then(() => { | ||
var _a2; | ||
this._providerReady = true; | ||
(_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */); | ||
})) == null ? void 0 : _e.catch(() => { | ||
var _a2; | ||
(_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */); | ||
}); | ||
} else { | ||
this._providerReady = true; | ||
(_f = this._provider.events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */); | ||
} | ||
this._apiEvents.emit("providerChanged" /* ProviderChanged */); | ||
(_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider); | ||
} | ||
@@ -418,3 +825,7 @@ return this; | ||
return new OpenFeatureClient( | ||
// functions are passed here to make sure that these values are always up to date, | ||
// and so we don't have to make these public properties on the API class. | ||
() => this._provider, | ||
() => this._providerReady, | ||
() => this._apiEvents, | ||
() => this._logger, | ||
@@ -429,4 +840,5 @@ { name, version } | ||
var OpenFeatureClient = class { | ||
constructor(providerAccessor, globalLogger, options) { | ||
constructor(providerAccessor, providerReady, apiEvents, globalLogger, options) { | ||
this.providerAccessor = providerAccessor; | ||
this.providerReady = providerReady; | ||
this.globalLogger = globalLogger; | ||
@@ -440,7 +852,9 @@ this._hooks = []; | ||
this.attachListeners(); | ||
window.dispatchEvent(new CustomEvent("providerChanged" /* ProviderChanged */)); | ||
apiEvents().on("providerChanged" /* ProviderChanged */, () => { | ||
this.attachListeners(); | ||
}); | ||
} | ||
addHandler(eventType, handler) { | ||
this._handlerWrappers.push({ eventType, handler }); | ||
if (eventType === "PROVIDER_READY" /* Ready */ && this.providerAccessor().ready) { | ||
if (eventType === "PROVIDER_READY" /* Ready */ && this.providerReady()) { | ||
handler(); | ||
@@ -528,3 +942,3 @@ } | ||
this.beforeHooks(allHooks, hookContext, options); | ||
const resolution = resolver.call(this._provider, flagKey, defaultValue, this._logger); | ||
const resolution = resolver.call(this._provider, flagKey, defaultValue, context, this._logger); | ||
const evaluationDetails = __spreadProps(__spreadValues({}, resolution), { | ||
@@ -599,7 +1013,10 @@ flagKey | ||
attachListeners() { | ||
Object.values(ProviderEvents).forEach((eventType) => window.addEventListener(eventType, () => { | ||
this._handlerWrappers.filter((wrapper) => wrapper.eventType === eventType).forEach((wrapper) => wrapper.handler()); | ||
})); | ||
Object.values(ProviderEvents).forEach((eventType) => { | ||
var _a; | ||
return (_a = this._provider.events) == null ? void 0 : _a.on(eventType, () => { | ||
this._handlerWrappers.filter((wrapper) => wrapper.eventType === eventType).forEach((wrapper) => wrapper.handler()); | ||
}); | ||
}); | ||
} | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -0,5 +1,9 @@ | ||
var __create = Object.create; | ||
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 __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
@@ -20,2 +24,21 @@ var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); | ||
var __commonJS = (cb, mod) => function __require() { | ||
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
// If the importer is in node compatibility mode or this is not an ESM | ||
// file that has been converted to a CommonJS file using a Babel- | ||
// compatible transform (i.e. "__esModule" has not been set), then set | ||
// "default" to the CommonJS "module.exports" for node compatibility. | ||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
mod | ||
)); | ||
var __async = (__this, __arguments, generator) => { | ||
@@ -42,2 +65,374 @@ return new Promise((resolve, reject) => { | ||
// ../../node_modules/events/events.js | ||
var require_events = __commonJS({ | ||
"../../node_modules/events/events.js"(exports, module) { | ||
"use strict"; | ||
var R = typeof Reflect === "object" ? Reflect : null; | ||
var ReflectApply = R && typeof R.apply === "function" ? R.apply : function ReflectApply2(target, receiver, args) { | ||
return Function.prototype.apply.call(target, receiver, args); | ||
}; | ||
var ReflectOwnKeys; | ||
if (R && typeof R.ownKeys === "function") { | ||
ReflectOwnKeys = R.ownKeys; | ||
} else if (Object.getOwnPropertySymbols) { | ||
ReflectOwnKeys = function ReflectOwnKeys2(target) { | ||
return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)); | ||
}; | ||
} else { | ||
ReflectOwnKeys = function ReflectOwnKeys2(target) { | ||
return Object.getOwnPropertyNames(target); | ||
}; | ||
} | ||
function ProcessEmitWarning(warning) { | ||
if (console && console.warn) | ||
console.warn(warning); | ||
} | ||
var NumberIsNaN = Number.isNaN || function NumberIsNaN2(value) { | ||
return value !== value; | ||
}; | ||
function EventEmitter2() { | ||
EventEmitter2.init.call(this); | ||
} | ||
module.exports = EventEmitter2; | ||
module.exports.once = once; | ||
EventEmitter2.EventEmitter = EventEmitter2; | ||
EventEmitter2.prototype._events = void 0; | ||
EventEmitter2.prototype._eventsCount = 0; | ||
EventEmitter2.prototype._maxListeners = void 0; | ||
var defaultMaxListeners = 10; | ||
function checkListener(listener) { | ||
if (typeof listener !== "function") { | ||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); | ||
} | ||
} | ||
Object.defineProperty(EventEmitter2, "defaultMaxListeners", { | ||
enumerable: true, | ||
get: function() { | ||
return defaultMaxListeners; | ||
}, | ||
set: function(arg) { | ||
if (typeof arg !== "number" || arg < 0 || NumberIsNaN(arg)) { | ||
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + "."); | ||
} | ||
defaultMaxListeners = arg; | ||
} | ||
}); | ||
EventEmitter2.init = function() { | ||
if (this._events === void 0 || this._events === Object.getPrototypeOf(this)._events) { | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
this._eventsCount = 0; | ||
} | ||
this._maxListeners = this._maxListeners || void 0; | ||
}; | ||
EventEmitter2.prototype.setMaxListeners = function setMaxListeners(n) { | ||
if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) { | ||
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + "."); | ||
} | ||
this._maxListeners = n; | ||
return this; | ||
}; | ||
function _getMaxListeners(that) { | ||
if (that._maxListeners === void 0) | ||
return EventEmitter2.defaultMaxListeners; | ||
return that._maxListeners; | ||
} | ||
EventEmitter2.prototype.getMaxListeners = function getMaxListeners() { | ||
return _getMaxListeners(this); | ||
}; | ||
EventEmitter2.prototype.emit = function emit(type) { | ||
var args = []; | ||
for (var i = 1; i < arguments.length; i++) | ||
args.push(arguments[i]); | ||
var doError = type === "error"; | ||
var events = this._events; | ||
if (events !== void 0) | ||
doError = doError && events.error === void 0; | ||
else if (!doError) | ||
return false; | ||
if (doError) { | ||
var er; | ||
if (args.length > 0) | ||
er = args[0]; | ||
if (er instanceof Error) { | ||
throw er; | ||
} | ||
var err = new Error("Unhandled error." + (er ? " (" + er.message + ")" : "")); | ||
err.context = er; | ||
throw err; | ||
} | ||
var handler = events[type]; | ||
if (handler === void 0) | ||
return false; | ||
if (typeof handler === "function") { | ||
ReflectApply(handler, this, args); | ||
} else { | ||
var len = handler.length; | ||
var listeners = arrayClone(handler, len); | ||
for (var i = 0; i < len; ++i) | ||
ReflectApply(listeners[i], this, args); | ||
} | ||
return true; | ||
}; | ||
function _addListener(target, type, listener, prepend) { | ||
var m; | ||
var events; | ||
var existing; | ||
checkListener(listener); | ||
events = target._events; | ||
if (events === void 0) { | ||
events = target._events = /* @__PURE__ */ Object.create(null); | ||
target._eventsCount = 0; | ||
} else { | ||
if (events.newListener !== void 0) { | ||
target.emit( | ||
"newListener", | ||
type, | ||
listener.listener ? listener.listener : listener | ||
); | ||
events = target._events; | ||
} | ||
existing = events[type]; | ||
} | ||
if (existing === void 0) { | ||
existing = events[type] = listener; | ||
++target._eventsCount; | ||
} else { | ||
if (typeof existing === "function") { | ||
existing = events[type] = prepend ? [listener, existing] : [existing, listener]; | ||
} else if (prepend) { | ||
existing.unshift(listener); | ||
} else { | ||
existing.push(listener); | ||
} | ||
m = _getMaxListeners(target); | ||
if (m > 0 && existing.length > m && !existing.warned) { | ||
existing.warned = true; | ||
var w = new Error("Possible EventEmitter memory leak detected. " + existing.length + " " + String(type) + " listeners added. Use emitter.setMaxListeners() to increase limit"); | ||
w.name = "MaxListenersExceededWarning"; | ||
w.emitter = target; | ||
w.type = type; | ||
w.count = existing.length; | ||
ProcessEmitWarning(w); | ||
} | ||
} | ||
return target; | ||
} | ||
EventEmitter2.prototype.addListener = function addListener(type, listener) { | ||
return _addListener(this, type, listener, false); | ||
}; | ||
EventEmitter2.prototype.on = EventEmitter2.prototype.addListener; | ||
EventEmitter2.prototype.prependListener = function prependListener(type, listener) { | ||
return _addListener(this, type, listener, true); | ||
}; | ||
function onceWrapper() { | ||
if (!this.fired) { | ||
this.target.removeListener(this.type, this.wrapFn); | ||
this.fired = true; | ||
if (arguments.length === 0) | ||
return this.listener.call(this.target); | ||
return this.listener.apply(this.target, arguments); | ||
} | ||
} | ||
function _onceWrap(target, type, listener) { | ||
var state = { fired: false, wrapFn: void 0, target, type, listener }; | ||
var wrapped = onceWrapper.bind(state); | ||
wrapped.listener = listener; | ||
state.wrapFn = wrapped; | ||
return wrapped; | ||
} | ||
EventEmitter2.prototype.once = function once2(type, listener) { | ||
checkListener(listener); | ||
this.on(type, _onceWrap(this, type, listener)); | ||
return this; | ||
}; | ||
EventEmitter2.prototype.prependOnceListener = function prependOnceListener(type, listener) { | ||
checkListener(listener); | ||
this.prependListener(type, _onceWrap(this, type, listener)); | ||
return this; | ||
}; | ||
EventEmitter2.prototype.removeListener = function removeListener(type, listener) { | ||
var list, events, position, i, originalListener; | ||
checkListener(listener); | ||
events = this._events; | ||
if (events === void 0) | ||
return this; | ||
list = events[type]; | ||
if (list === void 0) | ||
return this; | ||
if (list === listener || list.listener === listener) { | ||
if (--this._eventsCount === 0) | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
else { | ||
delete events[type]; | ||
if (events.removeListener) | ||
this.emit("removeListener", type, list.listener || listener); | ||
} | ||
} else if (typeof list !== "function") { | ||
position = -1; | ||
for (i = list.length - 1; i >= 0; i--) { | ||
if (list[i] === listener || list[i].listener === listener) { | ||
originalListener = list[i].listener; | ||
position = i; | ||
break; | ||
} | ||
} | ||
if (position < 0) | ||
return this; | ||
if (position === 0) | ||
list.shift(); | ||
else { | ||
spliceOne(list, position); | ||
} | ||
if (list.length === 1) | ||
events[type] = list[0]; | ||
if (events.removeListener !== void 0) | ||
this.emit("removeListener", type, originalListener || listener); | ||
} | ||
return this; | ||
}; | ||
EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener; | ||
EventEmitter2.prototype.removeAllListeners = function removeAllListeners(type) { | ||
var listeners, events, i; | ||
events = this._events; | ||
if (events === void 0) | ||
return this; | ||
if (events.removeListener === void 0) { | ||
if (arguments.length === 0) { | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
this._eventsCount = 0; | ||
} else if (events[type] !== void 0) { | ||
if (--this._eventsCount === 0) | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
else | ||
delete events[type]; | ||
} | ||
return this; | ||
} | ||
if (arguments.length === 0) { | ||
var keys = Object.keys(events); | ||
var key; | ||
for (i = 0; i < keys.length; ++i) { | ||
key = keys[i]; | ||
if (key === "removeListener") | ||
continue; | ||
this.removeAllListeners(key); | ||
} | ||
this.removeAllListeners("removeListener"); | ||
this._events = /* @__PURE__ */ Object.create(null); | ||
this._eventsCount = 0; | ||
return this; | ||
} | ||
listeners = events[type]; | ||
if (typeof listeners === "function") { | ||
this.removeListener(type, listeners); | ||
} else if (listeners !== void 0) { | ||
for (i = listeners.length - 1; i >= 0; i--) { | ||
this.removeListener(type, listeners[i]); | ||
} | ||
} | ||
return this; | ||
}; | ||
function _listeners(target, type, unwrap) { | ||
var events = target._events; | ||
if (events === void 0) | ||
return []; | ||
var evlistener = events[type]; | ||
if (evlistener === void 0) | ||
return []; | ||
if (typeof evlistener === "function") | ||
return unwrap ? [evlistener.listener || evlistener] : [evlistener]; | ||
return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); | ||
} | ||
EventEmitter2.prototype.listeners = function listeners(type) { | ||
return _listeners(this, type, true); | ||
}; | ||
EventEmitter2.prototype.rawListeners = function rawListeners(type) { | ||
return _listeners(this, type, false); | ||
}; | ||
EventEmitter2.listenerCount = function(emitter, type) { | ||
if (typeof emitter.listenerCount === "function") { | ||
return emitter.listenerCount(type); | ||
} else { | ||
return listenerCount.call(emitter, type); | ||
} | ||
}; | ||
EventEmitter2.prototype.listenerCount = listenerCount; | ||
function listenerCount(type) { | ||
var events = this._events; | ||
if (events !== void 0) { | ||
var evlistener = events[type]; | ||
if (typeof evlistener === "function") { | ||
return 1; | ||
} else if (evlistener !== void 0) { | ||
return evlistener.length; | ||
} | ||
} | ||
return 0; | ||
} | ||
EventEmitter2.prototype.eventNames = function eventNames() { | ||
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; | ||
}; | ||
function arrayClone(arr, n) { | ||
var copy = new Array(n); | ||
for (var i = 0; i < n; ++i) | ||
copy[i] = arr[i]; | ||
return copy; | ||
} | ||
function spliceOne(list, index) { | ||
for (; index + 1 < list.length; index++) | ||
list[index] = list[index + 1]; | ||
list.pop(); | ||
} | ||
function unwrapListeners(arr) { | ||
var ret = new Array(arr.length); | ||
for (var i = 0; i < ret.length; ++i) { | ||
ret[i] = arr[i].listener || arr[i]; | ||
} | ||
return ret; | ||
} | ||
function once(emitter, name) { | ||
return new Promise(function(resolve, reject) { | ||
function errorListener(err) { | ||
emitter.removeListener(name, resolver); | ||
reject(err); | ||
} | ||
function resolver() { | ||
if (typeof emitter.removeListener === "function") { | ||
emitter.removeListener("error", errorListener); | ||
} | ||
resolve([].slice.call(arguments)); | ||
} | ||
; | ||
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); | ||
if (name !== "error") { | ||
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); | ||
} | ||
}); | ||
} | ||
function addErrorHandlerIfEventEmitter(emitter, handler, flags) { | ||
if (typeof emitter.on === "function") { | ||
eventTargetAgnosticAddListener(emitter, "error", handler, flags); | ||
} | ||
} | ||
function eventTargetAgnosticAddListener(emitter, name, listener, flags) { | ||
if (typeof emitter.on === "function") { | ||
if (flags.once) { | ||
emitter.once(name, listener); | ||
} else { | ||
emitter.on(name, listener); | ||
} | ||
} else if (typeof emitter.addEventListener === "function") { | ||
emitter.addEventListener(name, function wrapListener(arg) { | ||
if (flags.once) { | ||
emitter.removeEventListener(name, wrapListener); | ||
} | ||
listener(arg); | ||
}); | ||
} else { | ||
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); | ||
} | ||
} | ||
} | ||
}); | ||
// ../shared/src/types.ts | ||
@@ -269,2 +664,5 @@ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => { | ||
// src/open-feature.ts | ||
var import_events = __toESM(require_events()); | ||
// src/no-op-provider.ts | ||
@@ -306,2 +704,4 @@ var REASON_NO_OP = "No-op"; | ||
super(); | ||
this._apiEvents = new import_events.EventEmitter(); | ||
this._providerReady = false; | ||
this._hooks = []; | ||
@@ -357,8 +757,25 @@ this._provider = NOOP_PROVIDER; | ||
setProvider(provider) { | ||
var _a; | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if (this._provider !== provider) { | ||
const oldProvider = this._provider; | ||
this._provider = provider; | ||
window.dispatchEvent(new CustomEvent("providerChanged" /* ProviderChanged */)); | ||
(_a = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _a.call(oldProvider); | ||
this._providerReady = false; | ||
if (!this._provider.events) { | ||
this._provider.events = new import_events.EventEmitter(); | ||
} | ||
if (typeof ((_a = this._provider) == null ? void 0 : _a.initialize) === "function") { | ||
(_e = (_d = (_c = (_b = this._provider).initialize) == null ? void 0 : _c.call(_b, this._context)) == null ? void 0 : _d.then(() => { | ||
var _a2; | ||
this._providerReady = true; | ||
(_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */); | ||
})) == null ? void 0 : _e.catch(() => { | ||
var _a2; | ||
(_a2 = this._provider.events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */); | ||
}); | ||
} else { | ||
this._providerReady = true; | ||
(_f = this._provider.events) == null ? void 0 : _f.emit("PROVIDER_READY" /* Ready */); | ||
} | ||
this._apiEvents.emit("providerChanged" /* ProviderChanged */); | ||
(_g = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _g.call(oldProvider); | ||
} | ||
@@ -375,3 +792,7 @@ return this; | ||
return new OpenFeatureClient( | ||
// functions are passed here to make sure that these values are always up to date, | ||
// and so we don't have to make these public properties on the API class. | ||
() => this._provider, | ||
() => this._providerReady, | ||
() => this._apiEvents, | ||
() => this._logger, | ||
@@ -386,4 +807,5 @@ { name, version } | ||
var OpenFeatureClient = class { | ||
constructor(providerAccessor, globalLogger, options) { | ||
constructor(providerAccessor, providerReady, apiEvents, globalLogger, options) { | ||
this.providerAccessor = providerAccessor; | ||
this.providerReady = providerReady; | ||
this.globalLogger = globalLogger; | ||
@@ -397,7 +819,9 @@ this._hooks = []; | ||
this.attachListeners(); | ||
window.dispatchEvent(new CustomEvent("providerChanged" /* ProviderChanged */)); | ||
apiEvents().on("providerChanged" /* ProviderChanged */, () => { | ||
this.attachListeners(); | ||
}); | ||
} | ||
addHandler(eventType, handler) { | ||
this._handlerWrappers.push({ eventType, handler }); | ||
if (eventType === "PROVIDER_READY" /* Ready */ && this.providerAccessor().ready) { | ||
if (eventType === "PROVIDER_READY" /* Ready */ && this.providerReady()) { | ||
handler(); | ||
@@ -485,3 +909,3 @@ } | ||
this.beforeHooks(allHooks, hookContext, options); | ||
const resolution = resolver.call(this._provider, flagKey, defaultValue, this._logger); | ||
const resolution = resolver.call(this._provider, flagKey, defaultValue, context, this._logger); | ||
const evaluationDetails = __spreadProps(__spreadValues({}, resolution), { | ||
@@ -556,5 +980,8 @@ flagKey | ||
attachListeners() { | ||
Object.values(ProviderEvents).forEach((eventType) => window.addEventListener(eventType, () => { | ||
this._handlerWrappers.filter((wrapper) => wrapper.eventType === eventType).forEach((wrapper) => wrapper.handler()); | ||
})); | ||
Object.values(ProviderEvents).forEach((eventType) => { | ||
var _a; | ||
return (_a = this._provider.events) == null ? void 0 : _a.on(eventType, () => { | ||
this._handlerWrappers.filter((wrapper) => wrapper.eventType === eventType).forEach((wrapper) => wrapper.handler()); | ||
}); | ||
}); | ||
} | ||
@@ -561,0 +988,0 @@ }; |
@@ -0,1 +1,3 @@ | ||
import EventEmitter, { EventEmitter as EventEmitter$1 } from 'events'; | ||
type PrimitiveValue = null | boolean | string | number; | ||
@@ -336,20 +338,42 @@ declare enum ProviderEvents { | ||
readonly hooks?: Hook[]; | ||
/** | ||
* An event emitter for ProviderEvents. | ||
* @see ProviderEvents | ||
*/ | ||
events?: EventEmitter; | ||
/** | ||
* A handler function to reconcile changes when the static context. | ||
* Called by the SDK when the context is changed. | ||
* | ||
* @param oldContext | ||
* @param newContext | ||
*/ | ||
onContextChange?(oldContext: EvaluationContext, newContext: EvaluationContext): Promise<void>; | ||
onClose?(): Promise<void>; | ||
/** | ||
* A handler function used to setup the provider. | ||
* Called by the SDK after the provider is set. | ||
* When the returned promise resolves, the SDK fires the ProviderEvents.Ready event. | ||
* If the returned promise rejects, the SDK fires the ProviderEvents.Error event. | ||
* Use this function to perform any context-dependent setup within the provider. | ||
* | ||
* @param context | ||
*/ | ||
initialize?(context: EvaluationContext): Promise<void>; | ||
/** | ||
* Resolve a boolean flag and its evaluation details. | ||
*/ | ||
resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, logger: Logger): ResolutionDetails<boolean>; | ||
resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext, logger: Logger): ResolutionDetails<boolean>; | ||
/** | ||
* Resolve a string flag and its evaluation details. | ||
*/ | ||
resolveStringEvaluation(flagKey: string, defaultValue: string, logger: Logger): ResolutionDetails<string>; | ||
resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext, logger: Logger): ResolutionDetails<string>; | ||
/** | ||
* Resolve a numeric flag and its evaluation details. | ||
*/ | ||
resolveNumberEvaluation(flagKey: string, defaultValue: number, logger: Logger): ResolutionDetails<number>; | ||
resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext, logger: Logger): ResolutionDetails<number>; | ||
/** | ||
* Resolve and parse an object flag and its evaluation details. | ||
*/ | ||
resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, logger: Logger): ResolutionDetails<T>; | ||
resolveObjectEvaluation<T extends JsonValue>(flagKey: string, defaultValue: T, context: EvaluationContext, logger: Logger): ResolutionDetails<T>; | ||
} | ||
@@ -532,5 +556,2 @@ interface Hook<T extends FlagValue = FlagValue> { | ||
} | ||
interface EventProvider { | ||
readonly ready: boolean; | ||
} | ||
@@ -543,2 +564,3 @@ type OpenFeatureClientOptions = { | ||
private readonly providerAccessor; | ||
private readonly providerReady; | ||
private readonly globalLogger; | ||
@@ -549,3 +571,3 @@ readonly metadata: ClientMetadata; | ||
private _handlerWrappers; | ||
constructor(providerAccessor: () => Provider & Partial<EventProvider>, globalLogger: () => Logger, options: OpenFeatureClientOptions); | ||
constructor(providerAccessor: () => Provider, providerReady: () => boolean, apiEvents: () => EventEmitter$1, globalLogger: () => Logger, options: OpenFeatureClientOptions); | ||
addHandler(eventType: ProviderEvents, handler: Handler): void; | ||
@@ -590,2 +612,4 @@ setLogger(logger: Logger): OpenFeatureClient; | ||
declare class OpenFeatureAPI extends OpenFeatureCommonAPI { | ||
private _apiEvents; | ||
private _providerReady; | ||
protected _hooks: Hook[]; | ||
@@ -623,2 +647,2 @@ protected _provider: Provider; | ||
export { ApiEvents, BeforeHookContext, Client, ClientMetadata, CommonProvider, DefaultLogger, ErrorCode, EvaluationContext, EvaluationContextValue, EvaluationDetails, EventCallbackMessage, EventContext, EventData, EventProvider, Eventing, Features, FlagEvaluationOptions, FlagNotFoundError, FlagValue, FlagValueType, GeneralError, GlobalApi, Handler, Hook, HookContext, HookHints, InvalidContextError, JsonArray, JsonObject, JsonValue, Logger, ManageContext, ManageLogger, ManageTransactionContextPropagator, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureCommonAPI, OpenFeatureError, ParseError, PrimitiveValue, Provider, ProviderEvents, ProviderMetadata, ResolutionDetails, ResolutionReason, SafeLogger, StandardResolutionReasons, TargetingKeyMissingError, TransactionContext, TransactionContextPropagator, TypeMismatchError }; | ||
export { ApiEvents, BeforeHookContext, Client, ClientMetadata, CommonProvider, DefaultLogger, ErrorCode, EvaluationContext, EvaluationContextValue, EvaluationDetails, EventCallbackMessage, EventContext, EventData, Eventing, Features, FlagEvaluationOptions, FlagNotFoundError, FlagValue, FlagValueType, GeneralError, GlobalApi, Handler, Hook, HookContext, HookHints, InvalidContextError, JsonArray, JsonObject, JsonValue, Logger, ManageContext, ManageLogger, ManageTransactionContextPropagator, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureCommonAPI, OpenFeatureError, ParseError, PrimitiveValue, Provider, ProviderEvents, ProviderMetadata, ResolutionDetails, ResolutionReason, SafeLogger, StandardResolutionReasons, TargetingKeyMissingError, TransactionContext, TransactionContextPropagator, TypeMismatchError }; |
{ | ||
"name": "@openfeature/web-sdk", | ||
"version": "0.1.0-experimental", | ||
"version": "0.2.0-experimental", | ||
"description": "OpenFeature SDK for Web", | ||
@@ -27,3 +27,3 @@ "main": "./dist/cjs/index.js", | ||
"prepack": "shx cp ./../../LICENSE ./LICENSE", | ||
"publish-if-not-exists": "cp $NPM_CONFIG_USERCONFIG .npmrc && if [ \"$(npm show $npm_package_name@$npm_package_version version)\" = \"$(npm run current-version -s)\" ]; then echo 'already published, skipping'; else npm publish --access public --tag experimental; fi", | ||
"publish-if-not-exists": "cp $NPM_CONFIG_USERCONFIG .npmrc && if [ \"$(npm show $npm_package_name@$npm_package_version version)\" = \"$(npm run current-version -s)\" ]; then echo 'already published, skipping'; else npm publish --access public; fi", | ||
"docs": "typedoc" | ||
@@ -30,0 +30,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
236719
54.31%2606
49.51%