@openfeature/web-sdk 0.4.13 → 0.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -24,374 +24,184 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  mod
25
25
  ));
26
26
 
27
- // ../../node_modules/events/events.js
28
- var require_events = __commonJS({
29
- "../../node_modules/events/events.js"(exports, module) {
27
+ // ../../node_modules/eventemitter3/index.js
28
+ var require_eventemitter3 = __commonJS({
29
+ "../../node_modules/eventemitter3/index.js"(exports, module) {
30
30
  "use strict";
31
- var R = typeof Reflect === "object" ? Reflect : null;
32
- var ReflectApply = R && typeof R.apply === "function" ? R.apply : function ReflectApply2(target, receiver, args) {
33
- return Function.prototype.apply.call(target, receiver, args);
34
- };
35
- var ReflectOwnKeys;
36
- if (R && typeof R.ownKeys === "function") {
37
- ReflectOwnKeys = R.ownKeys;
38
- } else if (Object.getOwnPropertySymbols) {
39
- ReflectOwnKeys = function ReflectOwnKeys2(target) {
40
- return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
41
- };
42
- } else {
43
- ReflectOwnKeys = function ReflectOwnKeys2(target) {
44
- return Object.getOwnPropertyNames(target);
45
- };
46
- }
47
- function ProcessEmitWarning(warning) {
48
- if (console && console.warn)
49
- console.warn(warning);
31
+ var has = Object.prototype.hasOwnProperty;
32
+ var prefix = "~";
33
+ function Events() {
34
+ }
35
+ if (Object.create) {
36
+ Events.prototype = /* @__PURE__ */ Object.create(null);
37
+ if (!new Events().__proto__)
38
+ prefix = false;
39
+ }
40
+ function EE(fn, context, once) {
41
+ this.fn = fn;
42
+ this.context = context;
43
+ this.once = once || false;
44
+ }
45
+ function addListener(emitter, event, fn, context, once) {
46
+ if (typeof fn !== "function") {
47
+ throw new TypeError("The listener must be a function");
48
+ }
49
+ var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
50
+ if (!emitter._events[evt])
51
+ emitter._events[evt] = listener, emitter._eventsCount++;
52
+ else if (!emitter._events[evt].fn)
53
+ emitter._events[evt].push(listener);
54
+ else
55
+ emitter._events[evt] = [emitter._events[evt], listener];
56
+ return emitter;
57
+ }
58
+ function clearEvent(emitter, evt) {
59
+ if (--emitter._eventsCount === 0)
60
+ emitter._events = new Events();
61
+ else
62
+ delete emitter._events[evt];
50
63
  }
51
- var NumberIsNaN = Number.isNaN || function NumberIsNaN2(value) {
52
- return value !== value;
53
- };
54
64
  function EventEmitter2() {
55
- EventEmitter2.init.call(this);
56
- }
57
- module.exports = EventEmitter2;
58
- module.exports.once = once;
59
- EventEmitter2.EventEmitter = EventEmitter2;
60
- EventEmitter2.prototype._events = void 0;
61
- EventEmitter2.prototype._eventsCount = 0;
62
- EventEmitter2.prototype._maxListeners = void 0;
63
- var defaultMaxListeners = 10;
64
- function checkListener(listener) {
65
- if (typeof listener !== "function") {
66
- throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
67
- }
65
+ this._events = new Events();
66
+ this._eventsCount = 0;
68
67
  }
69
- Object.defineProperty(EventEmitter2, "defaultMaxListeners", {
70
- enumerable: true,
71
- get: function() {
72
- return defaultMaxListeners;
73
- },
74
- set: function(arg) {
75
- if (typeof arg !== "number" || arg < 0 || NumberIsNaN(arg)) {
76
- throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + ".");
77
- }
78
- defaultMaxListeners = arg;
68
+ EventEmitter2.prototype.eventNames = function eventNames() {
69
+ var names = [], events, name;
70
+ if (this._eventsCount === 0)
71
+ return names;
72
+ for (name in events = this._events) {
73
+ if (has.call(events, name))
74
+ names.push(prefix ? name.slice(1) : name);
79
75
  }
80
- });
81
- EventEmitter2.init = function() {
82
- if (this._events === void 0 || this._events === Object.getPrototypeOf(this)._events) {
83
- this._events = /* @__PURE__ */ Object.create(null);
84
- this._eventsCount = 0;
76
+ if (Object.getOwnPropertySymbols) {
77
+ return names.concat(Object.getOwnPropertySymbols(events));
85
78
  }
86
- this._maxListeners = this._maxListeners || void 0;
79
+ return names;
87
80
  };
88
- EventEmitter2.prototype.setMaxListeners = function setMaxListeners(n) {
89
- if (typeof n !== "number" || n < 0 || NumberIsNaN(n)) {
90
- throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + ".");
81
+ EventEmitter2.prototype.listeners = function listeners(event) {
82
+ var evt = prefix ? prefix + event : event, handlers = this._events[evt];
83
+ if (!handlers)
84
+ return [];
85
+ if (handlers.fn)
86
+ return [handlers.fn];
87
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
88
+ ee[i] = handlers[i].fn;
91
89
  }
92
- this._maxListeners = n;
93
- return this;
90
+ return ee;
94
91
  };
95
- function _getMaxListeners(that) {
96
- if (that._maxListeners === void 0)
97
- return EventEmitter2.defaultMaxListeners;
98
- return that._maxListeners;
99
- }
100
- EventEmitter2.prototype.getMaxListeners = function getMaxListeners() {
101
- return _getMaxListeners(this);
92
+ EventEmitter2.prototype.listenerCount = function listenerCount(event) {
93
+ var evt = prefix ? prefix + event : event, listeners = this._events[evt];
94
+ if (!listeners)
95
+ return 0;
96
+ if (listeners.fn)
97
+ return 1;
98
+ return listeners.length;
102
99
  };
103
- EventEmitter2.prototype.emit = function emit(type) {
104
- var args = [];
105
- for (var i = 1; i < arguments.length; i++)
106
- args.push(arguments[i]);
107
- var doError = type === "error";
108
- var events = this._events;
109
- if (events !== void 0)
110
- doError = doError && events.error === void 0;
111
- else if (!doError)
100
+ EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
101
+ var evt = prefix ? prefix + event : event;
102
+ if (!this._events[evt])
112
103
  return false;
113
- if (doError) {
114
- var er;
115
- if (args.length > 0)
116
- er = args[0];
117
- if (er instanceof Error) {
118
- throw er;
104
+ var listeners = this._events[evt], len = arguments.length, args, i;
105
+ if (listeners.fn) {
106
+ if (listeners.once)
107
+ this.removeListener(event, listeners.fn, void 0, true);
108
+ switch (len) {
109
+ case 1:
110
+ return listeners.fn.call(listeners.context), true;
111
+ case 2:
112
+ return listeners.fn.call(listeners.context, a1), true;
113
+ case 3:
114
+ return listeners.fn.call(listeners.context, a1, a2), true;
115
+ case 4:
116
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
117
+ case 5:
118
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
119
+ case 6:
120
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
119
121
  }
120
- var err = new Error("Unhandled error." + (er ? " (" + er.message + ")" : ""));
121
- err.context = er;
122
- throw err;
123
- }
124
- var handler = events[type];
125
- if (handler === void 0)
126
- return false;
127
- if (typeof handler === "function") {
128
- ReflectApply(handler, this, args);
129
- } else {
130
- var len = handler.length;
131
- var listeners = arrayClone(handler, len);
132
- for (var i = 0; i < len; ++i)
133
- ReflectApply(listeners[i], this, args);
134
- }
135
- return true;
136
- };
137
- function _addListener(target, type, listener, prepend) {
138
- var m;
139
- var events;
140
- var existing;
141
- checkListener(listener);
142
- events = target._events;
143
- if (events === void 0) {
144
- events = target._events = /* @__PURE__ */ Object.create(null);
145
- target._eventsCount = 0;
146
- } else {
147
- if (events.newListener !== void 0) {
148
- target.emit(
149
- "newListener",
150
- type,
151
- listener.listener ? listener.listener : listener
152
- );
153
- events = target._events;
122
+ for (i = 1, args = new Array(len - 1); i < len; i++) {
123
+ args[i - 1] = arguments[i];
154
124
  }
155
- existing = events[type];
156
- }
157
- if (existing === void 0) {
158
- existing = events[type] = listener;
159
- ++target._eventsCount;
125
+ listeners.fn.apply(listeners.context, args);
160
126
  } else {
161
- if (typeof existing === "function") {
162
- existing = events[type] = prepend ? [listener, existing] : [existing, listener];
163
- } else if (prepend) {
164
- existing.unshift(listener);
165
- } else {
166
- existing.push(listener);
167
- }
168
- m = _getMaxListeners(target);
169
- if (m > 0 && existing.length > m && !existing.warned) {
170
- existing.warned = true;
171
- var w = new Error("Possible EventEmitter memory leak detected. " + existing.length + " " + String(type) + " listeners added. Use emitter.setMaxListeners() to increase limit");
172
- w.name = "MaxListenersExceededWarning";
173
- w.emitter = target;
174
- w.type = type;
175
- w.count = existing.length;
176
- ProcessEmitWarning(w);
127
+ var length = listeners.length, j;
128
+ for (i = 0; i < length; i++) {
129
+ if (listeners[i].once)
130
+ this.removeListener(event, listeners[i].fn, void 0, true);
131
+ switch (len) {
132
+ case 1:
133
+ listeners[i].fn.call(listeners[i].context);
134
+ break;
135
+ case 2:
136
+ listeners[i].fn.call(listeners[i].context, a1);
137
+ break;
138
+ case 3:
139
+ listeners[i].fn.call(listeners[i].context, a1, a2);
140
+ break;
141
+ case 4:
142
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
143
+ break;
144
+ default:
145
+ if (!args)
146
+ for (j = 1, args = new Array(len - 1); j < len; j++) {
147
+ args[j - 1] = arguments[j];
148
+ }
149
+ listeners[i].fn.apply(listeners[i].context, args);
150
+ }
177
151
  }
178
152
  }
179
- return target;
180
- }
181
- EventEmitter2.prototype.addListener = function addListener(type, listener) {
182
- return _addListener(this, type, listener, false);
183
- };
184
- EventEmitter2.prototype.on = EventEmitter2.prototype.addListener;
185
- EventEmitter2.prototype.prependListener = function prependListener(type, listener) {
186
- return _addListener(this, type, listener, true);
153
+ return true;
187
154
  };
188
- function onceWrapper() {
189
- if (!this.fired) {
190
- this.target.removeListener(this.type, this.wrapFn);
191
- this.fired = true;
192
- if (arguments.length === 0)
193
- return this.listener.call(this.target);
194
- return this.listener.apply(this.target, arguments);
195
- }
196
- }
197
- function _onceWrap(target, type, listener) {
198
- var state = { fired: false, wrapFn: void 0, target, type, listener };
199
- var wrapped = onceWrapper.bind(state);
200
- wrapped.listener = listener;
201
- state.wrapFn = wrapped;
202
- return wrapped;
203
- }
204
- EventEmitter2.prototype.once = function once2(type, listener) {
205
- checkListener(listener);
206
- this.on(type, _onceWrap(this, type, listener));
207
- return this;
155
+ EventEmitter2.prototype.on = function on(event, fn, context) {
156
+ return addListener(this, event, fn, context, false);
208
157
  };
209
- EventEmitter2.prototype.prependOnceListener = function prependOnceListener(type, listener) {
210
- checkListener(listener);
211
- this.prependListener(type, _onceWrap(this, type, listener));
212
- return this;
158
+ EventEmitter2.prototype.once = function once(event, fn, context) {
159
+ return addListener(this, event, fn, context, true);
213
160
  };
214
- EventEmitter2.prototype.removeListener = function removeListener(type, listener) {
215
- var list, events, position, i, originalListener;
216
- checkListener(listener);
217
- events = this._events;
218
- if (events === void 0)
161
+ EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
162
+ var evt = prefix ? prefix + event : event;
163
+ if (!this._events[evt])
219
164
  return this;
220
- list = events[type];
221
- if (list === void 0)
165
+ if (!fn) {
166
+ clearEvent(this, evt);
222
167
  return this;
223
- if (list === listener || list.listener === listener) {
224
- if (--this._eventsCount === 0)
225
- this._events = /* @__PURE__ */ Object.create(null);
226
- else {
227
- delete events[type];
228
- if (events.removeListener)
229
- this.emit("removeListener", type, list.listener || listener);
168
+ }
169
+ var listeners = this._events[evt];
170
+ if (listeners.fn) {
171
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
172
+ clearEvent(this, evt);
230
173
  }
231
- } else if (typeof list !== "function") {
232
- position = -1;
233
- for (i = list.length - 1; i >= 0; i--) {
234
- if (list[i] === listener || list[i].listener === listener) {
235
- originalListener = list[i].listener;
236
- position = i;
237
- break;
174
+ } else {
175
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
176
+ if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
177
+ events.push(listeners[i]);
238
178
  }
239
179
  }
240
- if (position < 0)
241
- return this;
242
- if (position === 0)
243
- list.shift();
244
- else {
245
- spliceOne(list, position);
246
- }
247
- if (list.length === 1)
248
- events[type] = list[0];
249
- if (events.removeListener !== void 0)
250
- this.emit("removeListener", type, originalListener || listener);
180
+ if (events.length)
181
+ this._events[evt] = events.length === 1 ? events[0] : events;
182
+ else
183
+ clearEvent(this, evt);
251
184
  }
252
185
  return this;
253
186
  };
254
- EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
255
- EventEmitter2.prototype.removeAllListeners = function removeAllListeners(type) {
256
- var listeners, events, i;
257
- events = this._events;
258
- if (events === void 0)
259
- return this;
260
- if (events.removeListener === void 0) {
261
- if (arguments.length === 0) {
262
- this._events = /* @__PURE__ */ Object.create(null);
263
- this._eventsCount = 0;
264
- } else if (events[type] !== void 0) {
265
- if (--this._eventsCount === 0)
266
- this._events = /* @__PURE__ */ Object.create(null);
267
- else
268
- delete events[type];
269
- }
270
- return this;
271
- }
272
- if (arguments.length === 0) {
273
- var keys = Object.keys(events);
274
- var key;
275
- for (i = 0; i < keys.length; ++i) {
276
- key = keys[i];
277
- if (key === "removeListener")
278
- continue;
279
- this.removeAllListeners(key);
280
- }
281
- this.removeAllListeners("removeListener");
282
- this._events = /* @__PURE__ */ Object.create(null);
187
+ EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
188
+ var evt;
189
+ if (event) {
190
+ evt = prefix ? prefix + event : event;
191
+ if (this._events[evt])
192
+ clearEvent(this, evt);
193
+ } else {
194
+ this._events = new Events();
283
195
  this._eventsCount = 0;
284
- return this;
285
- }
286
- listeners = events[type];
287
- if (typeof listeners === "function") {
288
- this.removeListener(type, listeners);
289
- } else if (listeners !== void 0) {
290
- for (i = listeners.length - 1; i >= 0; i--) {
291
- this.removeListener(type, listeners[i]);
292
- }
293
196
  }
294
197
  return this;
295
198
  };
296
- function _listeners(target, type, unwrap) {
297
- var events = target._events;
298
- if (events === void 0)
299
- return [];
300
- var evlistener = events[type];
301
- if (evlistener === void 0)
302
- return [];
303
- if (typeof evlistener === "function")
304
- return unwrap ? [evlistener.listener || evlistener] : [evlistener];
305
- return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
306
- }
307
- EventEmitter2.prototype.listeners = function listeners(type) {
308
- return _listeners(this, type, true);
309
- };
310
- EventEmitter2.prototype.rawListeners = function rawListeners(type) {
311
- return _listeners(this, type, false);
312
- };
313
- EventEmitter2.listenerCount = function(emitter, type) {
314
- if (typeof emitter.listenerCount === "function") {
315
- return emitter.listenerCount(type);
316
- } else {
317
- return listenerCount.call(emitter, type);
318
- }
319
- };
320
- EventEmitter2.prototype.listenerCount = listenerCount;
321
- function listenerCount(type) {
322
- var events = this._events;
323
- if (events !== void 0) {
324
- var evlistener = events[type];
325
- if (typeof evlistener === "function") {
326
- return 1;
327
- } else if (evlistener !== void 0) {
328
- return evlistener.length;
329
- }
330
- }
331
- return 0;
332
- }
333
- EventEmitter2.prototype.eventNames = function eventNames() {
334
- return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
335
- };
336
- function arrayClone(arr, n) {
337
- var copy = new Array(n);
338
- for (var i = 0; i < n; ++i)
339
- copy[i] = arr[i];
340
- return copy;
341
- }
342
- function spliceOne(list, index) {
343
- for (; index + 1 < list.length; index++)
344
- list[index] = list[index + 1];
345
- list.pop();
346
- }
347
- function unwrapListeners(arr) {
348
- var ret = new Array(arr.length);
349
- for (var i = 0; i < ret.length; ++i) {
350
- ret[i] = arr[i].listener || arr[i];
351
- }
352
- return ret;
353
- }
354
- function once(emitter, name) {
355
- return new Promise(function(resolve, reject) {
356
- function errorListener(err) {
357
- emitter.removeListener(name, resolver);
358
- reject(err);
359
- }
360
- function resolver() {
361
- if (typeof emitter.removeListener === "function") {
362
- emitter.removeListener("error", errorListener);
363
- }
364
- resolve([].slice.call(arguments));
365
- }
366
- ;
367
- eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
368
- if (name !== "error") {
369
- addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
370
- }
371
- });
372
- }
373
- function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
374
- if (typeof emitter.on === "function") {
375
- eventTargetAgnosticAddListener(emitter, "error", handler, flags);
376
- }
377
- }
378
- function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
379
- if (typeof emitter.on === "function") {
380
- if (flags.once) {
381
- emitter.once(name, listener);
382
- } else {
383
- emitter.on(name, listener);
384
- }
385
- } else if (typeof emitter.addEventListener === "function") {
386
- emitter.addEventListener(name, function wrapListener(arg) {
387
- if (flags.once) {
388
- emitter.removeEventListener(name, wrapListener);
389
- }
390
- listener(arg);
391
- });
392
- } else {
393
- throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
394
- }
199
+ EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
200
+ EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
201
+ EventEmitter2.prefixed = prefix;
202
+ EventEmitter2.EventEmitter = EventEmitter2;
203
+ if ("undefined" !== typeof module) {
204
+ module.exports = EventEmitter2;
395
205
  }
396
206
  }
397
207
  });
@@ -399,7 +209,8 @@ var require_events = __commonJS({
399
209
  // src/client/open-feature-client.ts
400
210
  import {
401
211
  ErrorCode as ErrorCode2,
402
- ProviderStatus as ProviderStatus3,
212
+ ProviderFatalError,
213
+ ProviderNotReadyError,
403
214
  SafeLogger,
404
215
  StandardResolutionReasons as StandardResolutionReasons2,
405
216
  statusMatchesEvent
@@ -408,36 +219,37 @@ import {
408
219
  // src/open-feature.ts
409
220
  import {
410
221
  OpenFeatureCommonAPI,
222
+ ProviderWrapper,
411
223
  objectOrUndefined,
412
224
  stringOrUndefined
413
225
  } from "@openfeature/core";
414
226
 
415
227
  // src/events/open-feature-event-emitter.ts
416
- var import_events = __toESM(require_events());
417
228
  import { GenericEventEmitter } from "@openfeature/core";
229
+
230
+ // ../../node_modules/eventemitter3/index.mjs
231
+ var import_index = __toESM(require_eventemitter3(), 1);
232
+
233
+ // src/events/open-feature-event-emitter.ts
418
234
  var OpenFeatureEventEmitter = class extends GenericEventEmitter {
419
- eventEmitter = new import_events.default({ captureRejections: true });
235
+ eventEmitter = new import_index.default();
420
236
  constructor() {
421
237
  super();
422
- this.eventEmitter.on("error", (err) => {
423
- this._logger?.error("Error running event handler:", err);
424
- });
425
238
  }
426
239
  };
427
240
 
428
241
  // src/events/events.ts
429
242
  import { ClientProviderEvents } from "@openfeature/core";
430
243
 
244
+ // src/provider/provider.ts
245
+ import { ClientProviderStatus } from "@openfeature/core";
246
+
431
247
  // src/provider/no-op-provider.ts
432
- import { ProviderStatus } from "@openfeature/core";
433
248
  var REASON_NO_OP = "No-op";
434
249
  var NoopFeatureProvider = class {
435
250
  metadata = {
436
251
  name: "No-op Provider"
437
252
  };
438
- get status() {
439
- return ProviderStatus.NOT_READY;
440
- }
441
253
  resolveBooleanEvaluation(_, defaultValue) {
442
254
  return this.noOp(defaultValue);
443
255
  }
@@ -465,8 +277,7 @@ import {
465
277
  GeneralError,
466
278
  OpenFeatureError as OpenFeatureError2,
467
279
  StandardResolutionReasons,
468
- TypeMismatchError,
469
- ProviderStatus as ProviderStatus2
280
+ TypeMismatchError
470
281
  } from "@openfeature/core";
471
282
 
472
283
  // src/provider/in-memory-provider/variant-not-found-error.ts
@@ -485,7 +296,6 @@ var VariantNotFoundError = class _VariantNotFoundError extends OpenFeatureError
485
296
  var InMemoryProvider = class {
486
297
  events = new OpenFeatureEventEmitter();
487
298
  runsOn = "client";
488
- status = ProviderStatus2.NOT_READY;
489
299
  metadata = {
490
300
  name: "in-memory"
491
301
  };
@@ -500,10 +310,8 @@ var InMemoryProvider = class {
500
310
  this.resolveFlagWithReason(key, context);
501
311
  }
502
312
  this._context = context;
503
- this.status = ProviderStatus2.READY;
504
- } catch (error) {
505
- this.status = ProviderStatus2.ERROR;
506
- throw error;
313
+ } catch (err) {
314
+ throw new Error("initialization failure", { cause: err });
507
315
  }
508
316
  }
509
317
  /**
@@ -512,13 +320,10 @@ var InMemoryProvider = class {
512
320
  */
513
321
  async putConfiguration(flagConfiguration) {
514
322
  const flagsChanged = Object.entries(flagConfiguration).filter(([key, value]) => this._flagConfiguration[key] !== value).map(([key]) => key);
515
- this.status = ProviderStatus2.STALE;
516
- this.events.emit(ClientProviderEvents.Stale);
517
323
  this._flagConfiguration = { ...flagConfiguration };
518
- this.events.emit(ClientProviderEvents.ConfigurationChanged, { flagsChanged });
519
324
  try {
520
325
  await this.initialize(this._context);
521
- this.events.emit(ClientProviderEvents.Ready);
326
+ this.events.emit(ClientProviderEvents.ConfigurationChanged, { flagsChanged });
522
327
  } catch (err) {
523
328
  this.events.emit(ClientProviderEvents.Error);
524
329
  throw err;
@@ -572,8 +377,7 @@ var InMemoryProvider = class {
572
377
  const isContextEval = ctx && flagSpec?.contextEvaluator;
573
378
  const variant = isContextEval ? flagSpec.contextEvaluator?.(ctx) : flagSpec.defaultVariant;
574
379
  const value = variant && flagSpec?.variants[variant];
575
- const evalReason = isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC;
576
- const reason = this.status === ProviderStatus2.STALE ? StandardResolutionReasons.CACHED : evalReason;
380
+ const reason = isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC;
577
381
  return {
578
382
  value,
579
383
  ...variant && { variant },
@@ -586,8 +390,10 @@ var InMemoryProvider = class {
586
390
  var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/web-sdk/api");
587
391
  var _globalThis = globalThis;
588
392
  var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
589
- _events = new OpenFeatureEventEmitter();
590
- _defaultProvider = NOOP_PROVIDER;
393
+ _statusEnumType = ClientProviderStatus;
394
+ _apiEmitter = new OpenFeatureEventEmitter();
395
+ _defaultProvider = new ProviderWrapper(NOOP_PROVIDER, ClientProviderStatus.NOT_READY, this._statusEnumType);
396
+ _domainScopedProviders = /* @__PURE__ */ new Map();
591
397
  _createEventEmitter = () => new OpenFeatureEventEmitter();
592
398
  constructor() {
593
399
  super("client");
@@ -606,33 +412,39 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
606
412
  _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
607
413
  return instance;
608
414
  }
415
+ getProviderStatus(domain) {
416
+ if (!domain) {
417
+ return this._defaultProvider.status;
418
+ }
419
+ return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;
420
+ }
609
421
  async setContext(domainOrContext, contextOrUndefined) {
610
422
  const domain = stringOrUndefined(domainOrContext);
611
423
  const context = objectOrUndefined(domainOrContext) ?? objectOrUndefined(contextOrUndefined) ?? {};
612
424
  if (domain) {
613
- const provider = this._domainScopedProviders.get(domain);
614
- if (provider) {
425
+ const wrapper = this._domainScopedProviders.get(domain);
426
+ if (wrapper) {
615
427
  const oldContext = this.getContext(domain);
616
428
  this._domainScopedContext.set(domain, context);
617
- await this.runProviderContextChangeHandler(domain, provider, oldContext, context);
429
+ await this.runProviderContextChangeHandler(domain, wrapper, oldContext, context);
618
430
  } else {
619
431
  this._domainScopedContext.set(domain, context);
620
432
  }
621
433
  } else {
622
434
  const oldContext = this._context;
623
435
  this._context = context;
624
- const unboundProviders = Array.from(this._domainScopedProviders.entries()).filter(([domain2]) => !this._domainScopedContext.has(domain2)).reduce((acc, [domain2, provider]) => {
625
- acc.push({ domain: domain2, provider });
436
+ const unboundProviders = Array.from(this._domainScopedProviders.entries()).filter(([domain2]) => !this._domainScopedContext.has(domain2)).reduce((acc, [domain2, wrapper]) => {
437
+ acc.push({ domain: domain2, wrapper });
626
438
  return acc;
627
439
  }, []);
628
- const allProviders = [
440
+ const allDomainRecords = [
629
441
  // add in the default (no domain)
630
- { domain: void 0, provider: this._defaultProvider },
442
+ { domain: void 0, wrapper: this._defaultProvider },
631
443
  ...unboundProviders
632
444
  ];
633
445
  await Promise.all(
634
- allProviders.map(
635
- (tuple) => this.runProviderContextChangeHandler(tuple.domain, tuple.provider, oldContext, context)
446
+ allDomainRecords.map(
447
+ (dm) => this.runProviderContextChangeHandler(dm.domain, dm.wrapper, oldContext, context)
636
448
  )
637
449
  );
638
450
  }
@@ -652,12 +464,12 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
652
464
  async clearContext(domainOrUndefined) {
653
465
  const domain = stringOrUndefined(domainOrUndefined);
654
466
  if (domain) {
655
- const provider = this._domainScopedProviders.get(domain);
656
- if (provider) {
467
+ const wrapper = this._domainScopedProviders.get(domain);
468
+ if (wrapper) {
657
469
  const oldContext = this.getContext(domain);
658
470
  this._domainScopedContext.delete(domain);
659
471
  const newContext = this.getContext();
660
- await this.runProviderContextChangeHandler(domain, provider, oldContext, newContext);
472
+ await this.runProviderContextChangeHandler(domain, wrapper, oldContext, newContext);
661
473
  } else {
662
474
  this._domainScopedContext.delete(domain);
663
475
  }
@@ -689,6 +501,7 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
689
501
  // functions are passed here to make sure that these values are always up to date,
690
502
  // and so we don't have to make these public properties on the API class.
691
503
  () => this.getProviderForClient(domain),
504
+ () => this.getProviderStatus(domain),
692
505
  () => this.buildAndCacheEventEmitterForClient(domain),
693
506
  () => this._logger,
694
507
  { domain, version }
@@ -702,22 +515,38 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
702
515
  await super.clearProvidersAndSetDefault(NOOP_PROVIDER);
703
516
  this._domainScopedContext.clear();
704
517
  }
705
- async runProviderContextChangeHandler(domain, provider, oldContext, newContext) {
706
- const providerName = provider.metadata.name;
518
+ async runProviderContextChangeHandler(domain, wrapper, oldContext, newContext) {
519
+ const providerName = wrapper.provider?.metadata?.name || "unnamed-provider";
707
520
  try {
708
- await provider.onContextChange?.(oldContext, newContext);
709
- this.getAssociatedEventEmitters(domain).forEach((emitter) => {
710
- emitter?.emit(ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
711
- });
712
- this._events?.emit(ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
521
+ if (typeof wrapper.provider.onContextChange === "function") {
522
+ wrapper.incrementPendingContextChanges();
523
+ wrapper.status = this._statusEnumType.RECONCILING;
524
+ this.getAssociatedEventEmitters(domain).forEach((emitter) => {
525
+ emitter?.emit(ClientProviderEvents.Reconciling, { domain, providerName });
526
+ });
527
+ this._apiEmitter?.emit(ClientProviderEvents.Reconciling, { domain, providerName });
528
+ await wrapper.provider.onContextChange(oldContext, newContext);
529
+ wrapper.decrementPendingContextChanges();
530
+ }
531
+ wrapper.status = this._statusEnumType.READY;
532
+ if (wrapper.allContextChangesSettled) {
533
+ this.getAssociatedEventEmitters(domain).forEach((emitter) => {
534
+ emitter?.emit(ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
535
+ });
536
+ this._apiEmitter?.emit(ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
537
+ }
713
538
  } catch (err) {
714
- const error = err;
715
- const message = `Error running ${provider?.metadata?.name}'s context change handler: ${error?.message}`;
716
- this._logger?.error(`${message}`, err);
717
- this.getAssociatedEventEmitters(domain).forEach((emitter) => {
718
- emitter?.emit(ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
719
- });
720
- this._events?.emit(ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
539
+ wrapper.decrementPendingContextChanges();
540
+ wrapper.status = this._statusEnumType.ERROR;
541
+ if (wrapper.allContextChangesSettled) {
542
+ const error = err;
543
+ const message = `Error running ${providerName}'s context change handler: ${error?.message}`;
544
+ this._logger?.error(`${message}`, err);
545
+ this.getAssociatedEventEmitters(domain).forEach((emitter) => {
546
+ emitter?.emit(ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
547
+ });
548
+ this._apiEmitter?.emit(ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
549
+ }
721
550
  }
722
551
  }
723
552
  };
@@ -725,8 +554,9 @@ var OpenFeature = OpenFeatureAPI.getInstance();
725
554
 
726
555
  // src/client/open-feature-client.ts
727
556
  var OpenFeatureClient = class {
728
- constructor(providerAccessor, emitterAccessor, globalLogger, options) {
557
+ constructor(providerAccessor, providerStatusAccessor, emitterAccessor, globalLogger, options) {
729
558
  this.providerAccessor = providerAccessor;
559
+ this.providerStatusAccessor = providerStatusAccessor;
730
560
  this.emitterAccessor = emitterAccessor;
731
561
  this.globalLogger = globalLogger;
732
562
  this.options = options;
@@ -743,11 +573,11 @@ var OpenFeatureClient = class {
743
573
  };
744
574
  }
745
575
  get providerStatus() {
746
- return this.providerAccessor()?.status || ProviderStatus3.READY;
576
+ return this.providerStatusAccessor();
747
577
  }
748
578
  addHandler(eventType, handler) {
749
579
  this.emitterAccessor().addHandler(eventType, handler);
750
- const shouldRunNow = statusMatchesEvent(eventType, this._provider.status);
580
+ const shouldRunNow = statusMatchesEvent(eventType, this.providerStatus);
751
581
  if (shouldRunNow) {
752
582
  try {
753
583
  handler({
@@ -841,6 +671,11 @@ var OpenFeatureClient = class {
841
671
  };
842
672
  try {
843
673
  this.beforeHooks(allHooks, hookContext, options);
674
+ if (this.providerStatus === ClientProviderStatus.NOT_READY) {
675
+ throw new ProviderNotReadyError("provider has not yet initialized");
676
+ } else if (this.providerStatus === ClientProviderStatus.FATAL) {
677
+ throw new ProviderFatalError("provider is in an irrecoverable error state");
678
+ }
844
679
  const resolution = resolver.call(this._provider, flagKey, defaultValue, context, this._logger);
845
680
  const evaluationDetails = {
846
681
  ...resolution,
@@ -920,6 +755,7 @@ export {
920
755
  OpenFeatureAPI,
921
756
  OpenFeatureClient,
922
757
  OpenFeatureEventEmitter,
923
- ClientProviderEvents as ProviderEvents
758
+ ClientProviderEvents as ProviderEvents,
759
+ ClientProviderStatus as ProviderStatus
924
760
  };
925
761
  //# sourceMappingURL=index.js.map