@openfeature/web-sdk 1.6.2 → 1.7.1

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/cjs/index.js CHANGED
@@ -235,13 +235,22 @@ var require_eventemitter3 = __commonJS({
235
235
  // src/index.ts
236
236
  var index_exports = {};
237
237
  __export(index_exports, {
238
+ AggregateError: () => AggregateError,
239
+ BaseEvaluationStrategy: () => BaseEvaluationStrategy,
240
+ ComparisonStrategy: () => ComparisonStrategy,
241
+ ErrorWithCode: () => ErrorWithCode,
242
+ FirstMatchStrategy: () => FirstMatchStrategy,
243
+ FirstSuccessfulStrategy: () => FirstSuccessfulStrategy,
238
244
  InMemoryProvider: () => InMemoryProvider,
245
+ MultiProvider: () => MultiProvider,
239
246
  NOOP_PROVIDER: () => NOOP_PROVIDER,
240
247
  OpenFeature: () => OpenFeature,
241
248
  OpenFeatureAPI: () => OpenFeatureAPI,
242
249
  OpenFeatureEventEmitter: () => OpenFeatureEventEmitter,
243
250
  ProviderEvents: () => import_core3.ClientProviderEvents,
244
- ProviderStatus: () => import_core.ClientProviderStatus
251
+ ProviderStatus: () => import_core.ClientProviderStatus,
252
+ constructAggregateError: () => constructAggregateError,
253
+ throwAggregateErrorFromPromiseResults: () => throwAggregateErrorFromPromiseResults
245
254
  });
246
255
  module.exports = __toCommonJS(index_exports);
247
256
 
@@ -392,11 +401,520 @@ var InMemoryProvider = class {
392
401
  }
393
402
  };
394
403
 
395
- // src/open-feature.ts
404
+ // src/provider/multi-provider/multi-provider-web.ts
405
+ var import_core9 = require("@openfeature/core");
406
+
407
+ // src/provider/multi-provider/hook-executor.ts
408
+ var HookExecutor = class {
409
+ constructor(logger) {
410
+ this.logger = logger;
411
+ }
412
+ beforeHooks(hooks, hookContext, hints) {
413
+ var _a;
414
+ for (const hook of hooks != null ? hooks : []) {
415
+ (_a = hook == null ? void 0 : hook.before) == null ? void 0 : _a.call(hook, hookContext, Object.freeze(hints));
416
+ }
417
+ }
418
+ afterHooks(hooks, hookContext, evaluationDetails, hints) {
419
+ var _a;
420
+ for (const hook of hooks != null ? hooks : []) {
421
+ (_a = hook == null ? void 0 : hook.after) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, hints);
422
+ }
423
+ }
424
+ errorHooks(hooks, hookContext, err, hints) {
425
+ var _a;
426
+ for (const hook of hooks != null ? hooks : []) {
427
+ try {
428
+ (_a = hook == null ? void 0 : hook.error) == null ? void 0 : _a.call(hook, hookContext, err, hints);
429
+ } catch (err2) {
430
+ this.logger.error(`Unhandled error during 'error' hook: ${err2}`);
431
+ if (err2 instanceof Error) {
432
+ this.logger.error(err2.stack);
433
+ }
434
+ }
435
+ }
436
+ }
437
+ finallyHooks(hooks, hookContext, evaluationDetails, hints) {
438
+ var _a;
439
+ for (const hook of hooks != null ? hooks : []) {
440
+ try {
441
+ (_a = hook == null ? void 0 : hook.finally) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, hints);
442
+ } catch (err) {
443
+ this.logger.error(`Unhandled error during 'finally' hook: ${err}`);
444
+ if (err instanceof Error) {
445
+ this.logger.error(err.stack);
446
+ }
447
+ }
448
+ }
449
+ }
450
+ };
451
+
452
+ // src/provider/multi-provider/errors.ts
453
+ var import_core6 = require("@openfeature/core");
454
+ var ErrorWithCode = class extends import_core6.OpenFeatureError {
455
+ constructor(code, message) {
456
+ super(message);
457
+ this.code = code;
458
+ }
459
+ };
460
+ var AggregateError = class extends import_core6.GeneralError {
461
+ constructor(message, originalErrors) {
462
+ super(message);
463
+ this.originalErrors = originalErrors;
464
+ }
465
+ };
466
+ var constructAggregateError = (providerErrors) => {
467
+ const errorsWithSource = providerErrors.map(({ providerName, error }) => {
468
+ return { source: providerName, error };
469
+ }).flat();
470
+ return new AggregateError(
471
+ `Provider errors occurred: ${errorsWithSource[0].source}: ${errorsWithSource[0].error}`,
472
+ errorsWithSource
473
+ );
474
+ };
475
+ var throwAggregateErrorFromPromiseResults = (result, providerEntries) => {
476
+ const errors = result.map((r, i) => {
477
+ if (r.status === "rejected") {
478
+ return { error: r.reason, providerName: providerEntries[i].name };
479
+ }
480
+ return null;
481
+ }).filter((val) => Boolean(val));
482
+ if (errors.length) {
483
+ throw constructAggregateError(errors);
484
+ }
485
+ };
486
+
487
+ // src/provider/multi-provider/strategies/base-evaluation-strategy.ts
488
+ var BaseEvaluationStrategy = class {
489
+ shouldEvaluateThisProvider(strategyContext, _evalContext) {
490
+ if (strategyContext.providerStatus === import_core.ClientProviderStatus.NOT_READY || strategyContext.providerStatus === import_core.ClientProviderStatus.FATAL) {
491
+ return false;
492
+ }
493
+ return true;
494
+ }
495
+ shouldEvaluateNextProvider(_strategyContext, _context, _result) {
496
+ return true;
497
+ }
498
+ shouldTrackWithThisProvider(strategyContext, _context, _trackingEventName, _trackingEventDetails) {
499
+ if (strategyContext.providerStatus === import_core.ClientProviderStatus.NOT_READY || strategyContext.providerStatus === import_core.ClientProviderStatus.FATAL) {
500
+ return false;
501
+ }
502
+ return true;
503
+ }
504
+ hasError(resolution) {
505
+ return "thrownError" in resolution || !!resolution.details.errorCode;
506
+ }
507
+ hasErrorWithCode(resolution, code) {
508
+ var _a;
509
+ return "thrownError" in resolution ? ((_a = resolution.thrownError) == null ? void 0 : _a.code) === code : resolution.details.errorCode === code;
510
+ }
511
+ collectProviderErrors(resolutions) {
512
+ var _a;
513
+ const errors = [];
514
+ for (const resolution of resolutions) {
515
+ if ("thrownError" in resolution) {
516
+ errors.push({ providerName: resolution.providerName, error: resolution.thrownError });
517
+ } else if (resolution.details.errorCode) {
518
+ errors.push({
519
+ providerName: resolution.providerName,
520
+ error: new ErrorWithCode(resolution.details.errorCode, (_a = resolution.details.errorMessage) != null ? _a : "unknown error")
521
+ });
522
+ }
523
+ }
524
+ return { errors };
525
+ }
526
+ resolutionToFinalResult(resolution) {
527
+ return { details: resolution.details, provider: resolution.provider, providerName: resolution.providerName };
528
+ }
529
+ };
530
+
531
+ // src/provider/multi-provider/strategies/first-match-strategy.ts
396
532
  var import_core7 = require("@openfeature/core");
533
+ var FirstMatchStrategy = class extends BaseEvaluationStrategy {
534
+ shouldEvaluateNextProvider(strategyContext, context, result) {
535
+ if (this.hasErrorWithCode(result, import_core7.ErrorCode.FLAG_NOT_FOUND)) {
536
+ return true;
537
+ }
538
+ if (this.hasError(result)) {
539
+ return false;
540
+ }
541
+ return false;
542
+ }
543
+ determineFinalResult(strategyContext, context, resolutions) {
544
+ const finalResolution = resolutions[resolutions.length - 1];
545
+ if (this.hasError(finalResolution)) {
546
+ return this.collectProviderErrors(resolutions);
547
+ }
548
+ return this.resolutionToFinalResult(finalResolution);
549
+ }
550
+ };
551
+
552
+ // src/provider/multi-provider/strategies/first-successful-strategy.ts
553
+ var FirstSuccessfulStrategy = class extends BaseEvaluationStrategy {
554
+ shouldEvaluateNextProvider(strategyContext, context, result) {
555
+ return this.hasError(result);
556
+ }
557
+ determineFinalResult(strategyContext, context, resolutions) {
558
+ const finalResolution = resolutions[resolutions.length - 1];
559
+ if (this.hasError(finalResolution)) {
560
+ return this.collectProviderErrors(resolutions);
561
+ }
562
+ return this.resolutionToFinalResult(finalResolution);
563
+ }
564
+ };
565
+
566
+ // src/provider/multi-provider/strategies/comparison-strategy.ts
567
+ var import_core8 = require("@openfeature/core");
568
+ var ComparisonStrategy = class extends BaseEvaluationStrategy {
569
+ constructor(fallbackProvider, onMismatch) {
570
+ super();
571
+ this.fallbackProvider = fallbackProvider;
572
+ this.onMismatch = onMismatch;
573
+ }
574
+ determineFinalResult(strategyContext, context, resolutions) {
575
+ var _a;
576
+ let value;
577
+ let fallbackResolution;
578
+ let finalResolution;
579
+ let mismatch = false;
580
+ for (const [i, resolution] of resolutions.entries()) {
581
+ if (this.hasError(resolution)) {
582
+ return this.collectProviderErrors(resolutions);
583
+ }
584
+ if (resolution.provider === this.fallbackProvider) {
585
+ fallbackResolution = resolution;
586
+ }
587
+ if (i === 0) {
588
+ finalResolution = resolution;
589
+ }
590
+ if (typeof value !== "undefined" && value !== resolution.details.value) {
591
+ mismatch = true;
592
+ } else {
593
+ value = resolution.details.value;
594
+ }
595
+ }
596
+ if (!fallbackResolution) {
597
+ throw new import_core8.GeneralError("Fallback provider not found in resolution results");
598
+ }
599
+ if (!finalResolution) {
600
+ throw new import_core8.GeneralError("Final resolution not found in resolution results");
601
+ }
602
+ if (mismatch) {
603
+ (_a = this.onMismatch) == null ? void 0 : _a.call(this, resolutions);
604
+ return {
605
+ details: fallbackResolution.details,
606
+ provider: fallbackResolution.provider
607
+ };
608
+ }
609
+ return this.resolutionToFinalResult(finalResolution);
610
+ }
611
+ };
612
+
613
+ // src/provider/multi-provider/status-tracker.ts
614
+ var StatusTracker = class {
615
+ constructor(events) {
616
+ this.events = events;
617
+ this.providerStatuses = {};
618
+ }
619
+ wrapEventHandler(providerEntry) {
620
+ var _a, _b, _c, _d, _e;
621
+ const provider = providerEntry.provider;
622
+ (_a = provider.events) == null ? void 0 : _a.addHandler(import_core3.ClientProviderEvents.Error, (details) => {
623
+ this.changeProviderStatus(providerEntry.name, import_core.ClientProviderStatus.ERROR, details);
624
+ });
625
+ (_b = provider.events) == null ? void 0 : _b.addHandler(import_core3.ClientProviderEvents.Stale, (details) => {
626
+ this.changeProviderStatus(providerEntry.name, import_core.ClientProviderStatus.STALE, details);
627
+ });
628
+ (_c = provider.events) == null ? void 0 : _c.addHandler(import_core3.ClientProviderEvents.ConfigurationChanged, (details) => {
629
+ this.events.emit(import_core3.ClientProviderEvents.ConfigurationChanged, details);
630
+ });
631
+ (_d = provider.events) == null ? void 0 : _d.addHandler(import_core3.ClientProviderEvents.Ready, (details) => {
632
+ this.changeProviderStatus(providerEntry.name, import_core.ClientProviderStatus.READY, details);
633
+ });
634
+ (_e = provider.events) == null ? void 0 : _e.addHandler(import_core3.ClientProviderEvents.Reconciling, (details) => {
635
+ this.changeProviderStatus(providerEntry.name, import_core.ClientProviderStatus.RECONCILING, details);
636
+ });
637
+ }
638
+ providerStatus(name) {
639
+ return this.providerStatuses[name];
640
+ }
641
+ getStatusFromProviderStatuses() {
642
+ const statuses = Object.values(this.providerStatuses);
643
+ if (statuses.includes(import_core.ClientProviderStatus.FATAL)) {
644
+ return import_core.ClientProviderStatus.FATAL;
645
+ } else if (statuses.includes(import_core.ClientProviderStatus.NOT_READY)) {
646
+ return import_core.ClientProviderStatus.NOT_READY;
647
+ } else if (statuses.includes(import_core.ClientProviderStatus.ERROR)) {
648
+ return import_core.ClientProviderStatus.ERROR;
649
+ } else if (statuses.includes(import_core.ClientProviderStatus.STALE)) {
650
+ return import_core.ClientProviderStatus.STALE;
651
+ } else if (statuses.includes(import_core.ClientProviderStatus.RECONCILING)) {
652
+ return import_core.ClientProviderStatus.RECONCILING;
653
+ }
654
+ return import_core.ClientProviderStatus.READY;
655
+ }
656
+ changeProviderStatus(name, status, details) {
657
+ const currentStatus = this.getStatusFromProviderStatuses();
658
+ this.providerStatuses[name] = status;
659
+ const newStatus = this.getStatusFromProviderStatuses();
660
+ if (currentStatus !== newStatus) {
661
+ if (newStatus === import_core.ClientProviderStatus.FATAL || newStatus === import_core.ClientProviderStatus.ERROR) {
662
+ this.events.emit(import_core3.ClientProviderEvents.Error, details);
663
+ } else if (newStatus === import_core.ClientProviderStatus.STALE) {
664
+ this.events.emit(import_core3.ClientProviderEvents.Stale, details);
665
+ } else if (newStatus === import_core.ClientProviderStatus.READY) {
666
+ this.events.emit(import_core3.ClientProviderEvents.Ready, details);
667
+ } else if (newStatus === import_core.ClientProviderStatus.RECONCILING) {
668
+ this.events.emit(import_core3.ClientProviderEvents.Reconciling, details);
669
+ }
670
+ }
671
+ }
672
+ };
673
+
674
+ // src/provider/multi-provider/multi-provider-web.ts
675
+ var MultiProvider = class _MultiProvider {
676
+ constructor(constructorProviders, evaluationStrategy = new FirstMatchStrategy(), logger = new import_core9.DefaultLogger()) {
677
+ this.constructorProviders = constructorProviders;
678
+ this.evaluationStrategy = evaluationStrategy;
679
+ this.logger = logger;
680
+ this.runsOn = "client";
681
+ this.events = new OpenFeatureEventEmitter();
682
+ this.hookContexts = /* @__PURE__ */ new WeakMap();
683
+ this.hookHints = /* @__PURE__ */ new WeakMap();
684
+ this.providerEntries = [];
685
+ this.providerEntriesByName = {};
686
+ this.statusTracker = new StatusTracker(this.events);
687
+ this.hookExecutor = new HookExecutor(this.logger);
688
+ this.registerProviders(constructorProviders);
689
+ const aggregateMetadata = Object.keys(this.providerEntriesByName).reduce((acc, name) => {
690
+ return __spreadProps(__spreadValues({}, acc), { [name]: this.providerEntriesByName[name].provider.metadata });
691
+ }, {});
692
+ this.metadata = __spreadProps(__spreadValues({}, aggregateMetadata), {
693
+ name: _MultiProvider.name
694
+ });
695
+ }
696
+ registerProviders(constructorProviders) {
697
+ var _a, _b;
698
+ const providersByName = {};
699
+ for (const constructorProvider of constructorProviders) {
700
+ const providerName = constructorProvider.provider.metadata.name;
701
+ const candidateName = (_a = constructorProvider.name) != null ? _a : providerName;
702
+ if (constructorProvider.name && providersByName[constructorProvider.name]) {
703
+ throw new Error("Provider names must be unique");
704
+ }
705
+ (_b = providersByName[candidateName]) != null ? _b : providersByName[candidateName] = [];
706
+ providersByName[candidateName].push(constructorProvider.provider);
707
+ }
708
+ for (const name of Object.keys(providersByName)) {
709
+ const useIndexedNames = providersByName[name].length > 1;
710
+ for (let i = 0; i < providersByName[name].length; i++) {
711
+ const indexedName = useIndexedNames ? `${name}-${i + 1}` : name;
712
+ this.providerEntriesByName[indexedName] = { provider: providersByName[name][i], name: indexedName };
713
+ this.providerEntries.push(this.providerEntriesByName[indexedName]);
714
+ this.statusTracker.wrapEventHandler(this.providerEntriesByName[indexedName]);
715
+ }
716
+ }
717
+ Object.freeze(this.providerEntries);
718
+ Object.freeze(this.providerEntriesByName);
719
+ }
720
+ initialize(context) {
721
+ return __async(this, null, function* () {
722
+ const result = yield Promise.allSettled(
723
+ this.providerEntries.map((provider) => {
724
+ var _a, _b;
725
+ return (_b = (_a = provider.provider).initialize) == null ? void 0 : _b.call(_a, context);
726
+ })
727
+ );
728
+ throwAggregateErrorFromPromiseResults(result, this.providerEntries);
729
+ });
730
+ }
731
+ onClose() {
732
+ return __async(this, null, function* () {
733
+ const result = yield Promise.allSettled(this.providerEntries.map((provider) => {
734
+ var _a, _b;
735
+ return (_b = (_a = provider.provider).onClose) == null ? void 0 : _b.call(_a);
736
+ }));
737
+ throwAggregateErrorFromPromiseResults(result, this.providerEntries);
738
+ });
739
+ }
740
+ onContextChange(oldContext, newContext) {
741
+ return __async(this, null, function* () {
742
+ var _a, _b;
743
+ for (const providerEntry of this.providerEntries) {
744
+ yield (_b = (_a = providerEntry.provider).onContextChange) == null ? void 0 : _b.call(_a, oldContext, newContext);
745
+ }
746
+ });
747
+ }
748
+ resolveBooleanEvaluation(flagKey, defaultValue, context) {
749
+ return this.flagResolutionProxy(flagKey, "boolean", defaultValue, context);
750
+ }
751
+ resolveStringEvaluation(flagKey, defaultValue, context) {
752
+ return this.flagResolutionProxy(flagKey, "string", defaultValue, context);
753
+ }
754
+ resolveNumberEvaluation(flagKey, defaultValue, context) {
755
+ return this.flagResolutionProxy(flagKey, "number", defaultValue, context);
756
+ }
757
+ resolveObjectEvaluation(flagKey, defaultValue, context) {
758
+ return this.flagResolutionProxy(flagKey, "object", defaultValue, context);
759
+ }
760
+ track(trackingEventName, context, trackingEventDetails) {
761
+ var _a, _b;
762
+ for (const providerEntry of this.providerEntries) {
763
+ if (!providerEntry.provider.track) {
764
+ continue;
765
+ }
766
+ const strategyContext = {
767
+ provider: providerEntry.provider,
768
+ providerName: providerEntry.name,
769
+ providerStatus: this.statusTracker.providerStatus(providerEntry.name)
770
+ };
771
+ if (this.evaluationStrategy.shouldTrackWithThisProvider(
772
+ strategyContext,
773
+ context,
774
+ trackingEventName,
775
+ trackingEventDetails
776
+ )) {
777
+ try {
778
+ (_b = (_a = providerEntry.provider).track) == null ? void 0 : _b.call(_a, trackingEventName, context, trackingEventDetails);
779
+ } catch (error) {
780
+ this.logger.error(
781
+ `Error tracking event "${trackingEventName}" with provider "${providerEntry.name}":`,
782
+ error
783
+ );
784
+ }
785
+ }
786
+ }
787
+ }
788
+ flagResolutionProxy(flagKey, flagType, defaultValue, context) {
789
+ var _a;
790
+ const hookContext = this.hookContexts.get(context);
791
+ const hookHints = this.hookHints.get(context);
792
+ if (!hookContext || !hookHints) {
793
+ throw new import_core9.GeneralError("Hook context not available for evaluation");
794
+ }
795
+ const results = [];
796
+ for (const providerEntry of this.providerEntries) {
797
+ const [shouldEvaluateNext, result] = this.evaluateProviderEntry(
798
+ flagKey,
799
+ flagType,
800
+ defaultValue,
801
+ providerEntry,
802
+ hookContext,
803
+ hookHints,
804
+ context
805
+ );
806
+ results.push(result);
807
+ if (!shouldEvaluateNext) {
808
+ break;
809
+ }
810
+ }
811
+ const resolutions = results.filter((r) => Boolean(r));
812
+ const finalResult = this.evaluationStrategy.determineFinalResult({ flagKey, flagType }, context, resolutions);
813
+ if ((_a = finalResult.errors) == null ? void 0 : _a.length) {
814
+ throw constructAggregateError(finalResult.errors);
815
+ }
816
+ if (!finalResult.details) {
817
+ throw new import_core9.GeneralError("No result was returned from any provider");
818
+ }
819
+ return finalResult.details;
820
+ }
821
+ evaluateProviderEntry(flagKey, flagType, defaultValue, providerEntry, hookContext, hookHints, context) {
822
+ let evaluationResult = void 0;
823
+ const provider = providerEntry.provider;
824
+ const strategyContext = {
825
+ flagKey,
826
+ flagType,
827
+ provider,
828
+ providerName: providerEntry.name,
829
+ providerStatus: this.statusTracker.providerStatus(providerEntry.name)
830
+ };
831
+ if (!this.evaluationStrategy.shouldEvaluateThisProvider(strategyContext, context)) {
832
+ return [true, null];
833
+ }
834
+ let resolution;
835
+ try {
836
+ evaluationResult = this.evaluateProviderAndHooks(flagKey, defaultValue, provider, hookContext, hookHints);
837
+ resolution = {
838
+ details: evaluationResult,
839
+ provider,
840
+ providerName: providerEntry.name
841
+ };
842
+ } catch (error) {
843
+ resolution = {
844
+ thrownError: error,
845
+ provider,
846
+ providerName: providerEntry.name
847
+ };
848
+ }
849
+ return [this.evaluationStrategy.shouldEvaluateNextProvider(strategyContext, context, resolution), resolution];
850
+ }
851
+ evaluateProviderAndHooks(flagKey, defaultValue, provider, hookContext, hookHints) {
852
+ var _a;
853
+ let evaluationDetails;
854
+ try {
855
+ this.hookExecutor.beforeHooks(provider.hooks, hookContext, hookHints);
856
+ const resolutionDetails = this.callProviderResolve(
857
+ provider,
858
+ flagKey,
859
+ defaultValue,
860
+ hookContext.context
861
+ );
862
+ evaluationDetails = __spreadProps(__spreadValues({}, resolutionDetails), {
863
+ flagMetadata: Object.freeze((_a = resolutionDetails.flagMetadata) != null ? _a : {}),
864
+ flagKey
865
+ });
866
+ this.hookExecutor.afterHooks(provider.hooks, hookContext, evaluationDetails, hookHints);
867
+ } catch (error) {
868
+ this.hookExecutor.errorHooks(provider.hooks, hookContext, error, hookHints);
869
+ evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, error);
870
+ }
871
+ this.hookExecutor.finallyHooks(provider.hooks, hookContext, evaluationDetails, hookHints);
872
+ return evaluationDetails;
873
+ }
874
+ callProviderResolve(provider, flagKey, defaultValue, context) {
875
+ switch (typeof defaultValue) {
876
+ case "string":
877
+ return provider.resolveStringEvaluation(flagKey, defaultValue, context, this.logger);
878
+ case "number":
879
+ return provider.resolveNumberEvaluation(flagKey, defaultValue, context, this.logger);
880
+ case "object":
881
+ return provider.resolveObjectEvaluation(flagKey, defaultValue, context, this.logger);
882
+ case "boolean":
883
+ return provider.resolveBooleanEvaluation(flagKey, defaultValue, context, this.logger);
884
+ default:
885
+ throw new import_core9.GeneralError("Invalid flag evaluation type");
886
+ }
887
+ }
888
+ get hooks() {
889
+ return [
890
+ {
891
+ before: (hookContext, hints) => {
892
+ this.hookContexts.set(hookContext.context, hookContext);
893
+ this.hookHints.set(hookContext.context, hints != null ? hints : {});
894
+ return hookContext.context;
895
+ }
896
+ }
897
+ ];
898
+ }
899
+ getErrorEvaluationDetails(flagKey, defaultValue, err, flagMetadata = {}) {
900
+ const errorMessage = err == null ? void 0 : err.message;
901
+ const errorCode = (err == null ? void 0 : err.code) || import_core9.ErrorCode.GENERAL;
902
+ return {
903
+ errorCode,
904
+ errorMessage,
905
+ value: defaultValue,
906
+ reason: import_core9.StandardResolutionReasons.ERROR,
907
+ flagMetadata: Object.freeze(flagMetadata),
908
+ flagKey
909
+ };
910
+ }
911
+ };
912
+
913
+ // src/open-feature.ts
914
+ var import_core11 = require("@openfeature/core");
397
915
 
398
916
  // src/client/internal/open-feature-client.ts
399
- var import_core6 = require("@openfeature/core");
917
+ var import_core10 = require("@openfeature/core");
400
918
  var OpenFeatureClient = class {
401
919
  constructor(providerAccessor, providerStatusAccessor, emitterAccessor, apiContextAccessor, apiHooksAccessor, globalLogger, options) {
402
920
  this.providerAccessor = providerAccessor;
@@ -424,7 +942,7 @@ var OpenFeatureClient = class {
424
942
  addHandler(eventType, handler, options) {
425
943
  var _a;
426
944
  this.emitterAccessor().addHandler(eventType, handler);
427
- const shouldRunNow = (0, import_core6.statusMatchesEvent)(eventType, this.providerStatus);
945
+ const shouldRunNow = (0, import_core10.statusMatchesEvent)(eventType, this.providerStatus);
428
946
  if (shouldRunNow) {
429
947
  try {
430
948
  handler({
@@ -449,7 +967,7 @@ var OpenFeatureClient = class {
449
967
  return this.emitterAccessor().getHandlers(eventType);
450
968
  }
451
969
  setLogger(logger) {
452
- this._clientLogger = new import_core6.SafeLogger(logger);
970
+ this._clientLogger = new import_core10.SafeLogger(logger);
453
971
  return this;
454
972
  }
455
973
  addHooks(...hooks) {
@@ -534,7 +1052,7 @@ var OpenFeatureClient = class {
534
1052
  providerMetadata: this._provider.metadata,
535
1053
  context,
536
1054
  logger: this._logger,
537
- hookData: new import_core6.MapHookData()
1055
+ hookData: new import_core10.MapHookData()
538
1056
  })
539
1057
  );
540
1058
  let evaluationDetails;
@@ -547,7 +1065,7 @@ var OpenFeatureClient = class {
547
1065
  flagKey
548
1066
  });
549
1067
  if (resolutionDetails.errorCode) {
550
- const err = (0, import_core6.instantiateErrorByErrorCode)(resolutionDetails.errorCode, resolutionDetails.errorMessage);
1068
+ const err = (0, import_core10.instantiateErrorByErrorCode)(resolutionDetails.errorCode, resolutionDetails.errorMessage);
551
1069
  this.errorHooks(allHooksReversed, hookContexts, err, options);
552
1070
  evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, err, resolutionDetails.flagMetadata);
553
1071
  } else {
@@ -616,19 +1134,19 @@ var OpenFeatureClient = class {
616
1134
  }
617
1135
  shortCircuitIfNotReady() {
618
1136
  if (this.providerStatus === import_core.ClientProviderStatus.NOT_READY) {
619
- throw new import_core6.ProviderNotReadyError("provider has not yet initialized");
1137
+ throw new import_core10.ProviderNotReadyError("provider has not yet initialized");
620
1138
  } else if (this.providerStatus === import_core.ClientProviderStatus.FATAL) {
621
- throw new import_core6.ProviderFatalError("provider is in an irrecoverable error state");
1139
+ throw new import_core10.ProviderFatalError("provider is in an irrecoverable error state");
622
1140
  }
623
1141
  }
624
1142
  getErrorEvaluationDetails(flagKey, defaultValue, err, flagMetadata = {}) {
625
1143
  const errorMessage = err == null ? void 0 : err.message;
626
- const errorCode = (err == null ? void 0 : err.code) || import_core6.ErrorCode.GENERAL;
1144
+ const errorCode = (err == null ? void 0 : err.code) || import_core10.ErrorCode.GENERAL;
627
1145
  return {
628
1146
  errorCode,
629
1147
  errorMessage,
630
1148
  value: defaultValue,
631
- reason: import_core6.StandardResolutionReasons.ERROR,
1149
+ reason: import_core10.StandardResolutionReasons.ERROR,
632
1150
  flagMetadata: Object.freeze(flagMetadata),
633
1151
  flagKey
634
1152
  };
@@ -638,12 +1156,12 @@ var OpenFeatureClient = class {
638
1156
  // src/open-feature.ts
639
1157
  var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/web-sdk/api");
640
1158
  var _globalThis = globalThis;
641
- var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommonAPI {
1159
+ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core11.OpenFeatureCommonAPI {
642
1160
  constructor() {
643
1161
  super("client");
644
1162
  this._statusEnumType = import_core.ClientProviderStatus;
645
1163
  this._apiEmitter = new OpenFeatureEventEmitter();
646
- this._defaultProvider = new import_core7.ProviderWrapper(
1164
+ this._defaultProvider = new import_core11.ProviderWrapper(
647
1165
  NOOP_PROVIDER,
648
1166
  import_core.ClientProviderStatus.NOT_READY,
649
1167
  this._statusEnumType
@@ -674,9 +1192,9 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommo
674
1192
  }
675
1193
  setProviderAndWait(clientOrProvider, providerContextOrUndefined, contextOrUndefined) {
676
1194
  return __async(this, null, function* () {
677
- const domain = (0, import_core7.stringOrUndefined)(clientOrProvider);
678
- const provider = domain ? (0, import_core7.objectOrUndefined)(providerContextOrUndefined) : (0, import_core7.objectOrUndefined)(clientOrProvider);
679
- const context = domain ? (0, import_core7.objectOrUndefined)(contextOrUndefined) : (0, import_core7.objectOrUndefined)(providerContextOrUndefined);
1195
+ const domain = (0, import_core11.stringOrUndefined)(clientOrProvider);
1196
+ const provider = domain ? (0, import_core11.objectOrUndefined)(providerContextOrUndefined) : (0, import_core11.objectOrUndefined)(clientOrProvider);
1197
+ const context = domain ? (0, import_core11.objectOrUndefined)(contextOrUndefined) : (0, import_core11.objectOrUndefined)(providerContextOrUndefined);
680
1198
  if (context) {
681
1199
  if (domain) {
682
1200
  this._domainScopedContext.set(domain, context);
@@ -688,9 +1206,9 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommo
688
1206
  });
689
1207
  }
690
1208
  setProvider(domainOrProvider, providerContextOrUndefined, contextOrUndefined) {
691
- const domain = (0, import_core7.stringOrUndefined)(domainOrProvider);
692
- const provider = domain ? (0, import_core7.objectOrUndefined)(providerContextOrUndefined) : (0, import_core7.objectOrUndefined)(domainOrProvider);
693
- const context = domain ? (0, import_core7.objectOrUndefined)(contextOrUndefined) : (0, import_core7.objectOrUndefined)(providerContextOrUndefined);
1209
+ const domain = (0, import_core11.stringOrUndefined)(domainOrProvider);
1210
+ const provider = domain ? (0, import_core11.objectOrUndefined)(providerContextOrUndefined) : (0, import_core11.objectOrUndefined)(domainOrProvider);
1211
+ const context = domain ? (0, import_core11.objectOrUndefined)(contextOrUndefined) : (0, import_core11.objectOrUndefined)(providerContextOrUndefined);
694
1212
  if (context) {
695
1213
  if (domain) {
696
1214
  this._domainScopedContext.set(domain, context);
@@ -710,8 +1228,8 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommo
710
1228
  setContext(domainOrContext, contextOrUndefined) {
711
1229
  return __async(this, null, function* () {
712
1230
  var _a, _b;
713
- const domain = (0, import_core7.stringOrUndefined)(domainOrContext);
714
- const context = (_b = (_a = (0, import_core7.objectOrUndefined)(domainOrContext)) != null ? _a : (0, import_core7.objectOrUndefined)(contextOrUndefined)) != null ? _b : {};
1231
+ const domain = (0, import_core11.stringOrUndefined)(domainOrContext);
1232
+ const context = (_b = (_a = (0, import_core11.objectOrUndefined)(domainOrContext)) != null ? _a : (0, import_core11.objectOrUndefined)(contextOrUndefined)) != null ? _b : {};
715
1233
  if (domain) {
716
1234
  const wrapper = this._domainScopedProviders.get(domain);
717
1235
  if (wrapper) {
@@ -740,7 +1258,7 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommo
740
1258
  });
741
1259
  }
742
1260
  getContext(domainOrUndefined) {
743
- const domain = (0, import_core7.stringOrUndefined)(domainOrUndefined);
1261
+ const domain = (0, import_core11.stringOrUndefined)(domainOrUndefined);
744
1262
  if (domain) {
745
1263
  const context = this._domainScopedContext.get(domain);
746
1264
  if (context) {
@@ -753,7 +1271,7 @@ var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommo
753
1271
  }
754
1272
  clearContext(domainOrUndefined) {
755
1273
  return __async(this, null, function* () {
756
- const domain = (0, import_core7.stringOrUndefined)(domainOrUndefined);
1274
+ const domain = (0, import_core11.stringOrUndefined)(domainOrUndefined);
757
1275
  if (domain) {
758
1276
  const wrapper = this._domainScopedProviders.get(domain);
759
1277
  if (wrapper) {