@openfeature/web-sdk 1.0.3 → 1.2.0
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/README.md +33 -5
- package/dist/cjs/index.js +355 -259
- package/dist/cjs/index.js.map +4 -4
- package/dist/esm/index.js +358 -261
- package/dist/esm/index.js.map +4 -4
- package/dist/types.d.ts +85 -57
- package/package.json +5 -5
package/dist/cjs/index.js
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
9
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
10
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
11
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
|
+
var __reflectGet = Reflect.get;
|
|
13
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
14
|
+
var __spreadValues = (a, b) => {
|
|
15
|
+
for (var prop in b || (b = {}))
|
|
16
|
+
if (__hasOwnProp.call(b, prop))
|
|
17
|
+
__defNormalProp(a, prop, b[prop]);
|
|
18
|
+
if (__getOwnPropSymbols)
|
|
19
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
20
|
+
if (__propIsEnum.call(b, prop))
|
|
21
|
+
__defNormalProp(a, prop, b[prop]);
|
|
22
|
+
}
|
|
23
|
+
return a;
|
|
24
|
+
};
|
|
25
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
8
26
|
var __commonJS = (cb, mod) => function __require() {
|
|
9
27
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
28
|
};
|
|
@@ -30,6 +48,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
48
|
mod
|
|
31
49
|
));
|
|
32
50
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
51
|
+
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
|
|
52
|
+
var __async = (__this, __arguments, generator) => {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
var fulfilled = (value) => {
|
|
55
|
+
try {
|
|
56
|
+
step(generator.next(value));
|
|
57
|
+
} catch (e) {
|
|
58
|
+
reject(e);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var rejected = (value) => {
|
|
62
|
+
try {
|
|
63
|
+
step(generator.throw(value));
|
|
64
|
+
} catch (e) {
|
|
65
|
+
reject(e);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
69
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
70
|
+
});
|
|
71
|
+
};
|
|
33
72
|
|
|
34
73
|
// ../../node_modules/eventemitter3/index.js
|
|
35
74
|
var require_eventemitter3 = __commonJS({
|
|
@@ -220,45 +259,23 @@ __export(src_exports, {
|
|
|
220
259
|
NOOP_PROVIDER: () => NOOP_PROVIDER,
|
|
221
260
|
OpenFeature: () => OpenFeature,
|
|
222
261
|
OpenFeatureAPI: () => OpenFeatureAPI,
|
|
223
|
-
OpenFeatureClient: () => OpenFeatureClient,
|
|
224
262
|
OpenFeatureEventEmitter: () => OpenFeatureEventEmitter,
|
|
225
|
-
ProviderEvents: () =>
|
|
226
|
-
ProviderStatus: () =>
|
|
263
|
+
ProviderEvents: () => import_core3.ClientProviderEvents,
|
|
264
|
+
ProviderStatus: () => import_core.ClientProviderStatus
|
|
227
265
|
});
|
|
228
266
|
module.exports = __toCommonJS(src_exports);
|
|
229
267
|
|
|
230
|
-
// src/client/open-feature-client.ts
|
|
231
|
-
var import_core7 = require("@openfeature/core");
|
|
232
|
-
|
|
233
|
-
// src/open-feature.ts
|
|
234
|
-
var import_core6 = require("@openfeature/core");
|
|
235
|
-
|
|
236
|
-
// src/events/open-feature-event-emitter.ts
|
|
237
|
-
var import_core = require("@openfeature/core");
|
|
238
|
-
|
|
239
|
-
// ../../node_modules/eventemitter3/index.mjs
|
|
240
|
-
var import_index = __toESM(require_eventemitter3(), 1);
|
|
241
|
-
|
|
242
|
-
// src/events/open-feature-event-emitter.ts
|
|
243
|
-
var OpenFeatureEventEmitter = class extends import_core.GenericEventEmitter {
|
|
244
|
-
eventEmitter = new import_index.default();
|
|
245
|
-
constructor() {
|
|
246
|
-
super();
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
// src/events/events.ts
|
|
251
|
-
var import_core2 = require("@openfeature/core");
|
|
252
|
-
|
|
253
268
|
// src/provider/provider.ts
|
|
254
|
-
var
|
|
269
|
+
var import_core = require("@openfeature/core");
|
|
255
270
|
|
|
256
271
|
// src/provider/no-op-provider.ts
|
|
257
272
|
var REASON_NO_OP = "No-op";
|
|
258
273
|
var NoopFeatureProvider = class {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
274
|
+
constructor() {
|
|
275
|
+
this.metadata = {
|
|
276
|
+
name: "No-op Provider"
|
|
277
|
+
};
|
|
278
|
+
}
|
|
262
279
|
resolveBooleanEvaluation(_, defaultValue) {
|
|
263
280
|
return this.noOp(defaultValue);
|
|
264
281
|
}
|
|
@@ -283,10 +300,26 @@ var NOOP_PROVIDER = new NoopFeatureProvider();
|
|
|
283
300
|
// src/provider/in-memory-provider/in-memory-provider.ts
|
|
284
301
|
var import_core5 = require("@openfeature/core");
|
|
285
302
|
|
|
303
|
+
// src/events/open-feature-event-emitter.ts
|
|
304
|
+
var import_core2 = require("@openfeature/core");
|
|
305
|
+
|
|
306
|
+
// ../../node_modules/eventemitter3/index.mjs
|
|
307
|
+
var import_index = __toESM(require_eventemitter3(), 1);
|
|
308
|
+
|
|
309
|
+
// src/events/open-feature-event-emitter.ts
|
|
310
|
+
var OpenFeatureEventEmitter = class extends import_core2.GenericEventEmitter {
|
|
311
|
+
constructor() {
|
|
312
|
+
super();
|
|
313
|
+
this.eventEmitter = new import_index.default();
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
// src/events/events.ts
|
|
318
|
+
var import_core3 = require("@openfeature/core");
|
|
319
|
+
|
|
286
320
|
// src/provider/in-memory-provider/variant-not-found-error.ts
|
|
287
321
|
var import_core4 = require("@openfeature/core");
|
|
288
322
|
var VariantNotFoundError = class _VariantNotFoundError extends import_core4.OpenFeatureError {
|
|
289
|
-
code;
|
|
290
323
|
constructor(message) {
|
|
291
324
|
super(message);
|
|
292
325
|
Object.setPrototypeOf(this, _VariantNotFoundError.prototype);
|
|
@@ -297,40 +330,42 @@ var VariantNotFoundError = class _VariantNotFoundError extends import_core4.Open
|
|
|
297
330
|
|
|
298
331
|
// src/provider/in-memory-provider/in-memory-provider.ts
|
|
299
332
|
var InMemoryProvider = class {
|
|
300
|
-
events = new OpenFeatureEventEmitter();
|
|
301
|
-
runsOn = "client";
|
|
302
|
-
metadata = {
|
|
303
|
-
name: "in-memory"
|
|
304
|
-
};
|
|
305
|
-
_flagConfiguration;
|
|
306
|
-
_context;
|
|
307
333
|
constructor(flagConfiguration = {}) {
|
|
308
|
-
this.
|
|
334
|
+
this.events = new OpenFeatureEventEmitter();
|
|
335
|
+
this.runsOn = "client";
|
|
336
|
+
this.metadata = {
|
|
337
|
+
name: "in-memory"
|
|
338
|
+
};
|
|
339
|
+
this._flagConfiguration = __spreadValues({}, flagConfiguration);
|
|
309
340
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
341
|
+
initialize(context) {
|
|
342
|
+
return __async(this, null, function* () {
|
|
343
|
+
try {
|
|
344
|
+
for (const key in this._flagConfiguration) {
|
|
345
|
+
this.resolveFlagWithReason(key, context);
|
|
346
|
+
}
|
|
347
|
+
this._context = context;
|
|
348
|
+
} catch (err) {
|
|
349
|
+
throw new import_core5.GeneralError("initialization failure", { cause: err });
|
|
314
350
|
}
|
|
315
|
-
|
|
316
|
-
} catch (err) {
|
|
317
|
-
throw new Error("initialization failure", { cause: err });
|
|
318
|
-
}
|
|
351
|
+
});
|
|
319
352
|
}
|
|
320
353
|
/**
|
|
321
354
|
* Overwrites the configured flags.
|
|
322
355
|
* @param { FlagConfiguration } flagConfiguration new flag configuration
|
|
323
356
|
*/
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
357
|
+
putConfiguration(flagConfiguration) {
|
|
358
|
+
return __async(this, null, function* () {
|
|
359
|
+
const flagsChanged = Object.entries(flagConfiguration).filter(([key, value]) => this._flagConfiguration[key] !== value).map(([key]) => key);
|
|
360
|
+
this._flagConfiguration = __spreadValues({}, flagConfiguration);
|
|
361
|
+
try {
|
|
362
|
+
yield this.initialize(this._context);
|
|
363
|
+
this.events.emit(import_core3.ClientProviderEvents.ConfigurationChanged, { flagsChanged });
|
|
364
|
+
} catch (err) {
|
|
365
|
+
this.events.emit(import_core3.ClientProviderEvents.Error);
|
|
366
|
+
throw err;
|
|
367
|
+
}
|
|
368
|
+
});
|
|
334
369
|
}
|
|
335
370
|
resolveBooleanEvaluation(flagKey, defaultValue, context, logger) {
|
|
336
371
|
return this.resolveAndCheckFlag(flagKey, defaultValue, context || this._context, logger);
|
|
@@ -347,7 +382,7 @@ var InMemoryProvider = class {
|
|
|
347
382
|
resolveAndCheckFlag(flagKey, defaultValue, context, logger) {
|
|
348
383
|
if (!(flagKey in this._flagConfiguration)) {
|
|
349
384
|
const message = `no flag found with key ${flagKey}`;
|
|
350
|
-
logger
|
|
385
|
+
logger == null ? void 0 : logger.debug(message);
|
|
351
386
|
throw new import_core5.FlagNotFoundError(message);
|
|
352
387
|
}
|
|
353
388
|
if (this._flagConfiguration[flagKey].disabled) {
|
|
@@ -356,7 +391,7 @@ var InMemoryProvider = class {
|
|
|
356
391
|
const resolvedFlag = this.resolveFlagWithReason(flagKey, context);
|
|
357
392
|
if (resolvedFlag.value === void 0) {
|
|
358
393
|
const message = `no value associated with variant provided for ${flagKey} found`;
|
|
359
|
-
logger
|
|
394
|
+
logger == null ? void 0 : logger.error(message);
|
|
360
395
|
throw new VariantNotFoundError(message);
|
|
361
396
|
}
|
|
362
397
|
if (typeof resolvedFlag.value != typeof defaultValue) {
|
|
@@ -370,192 +405,31 @@ var InMemoryProvider = class {
|
|
|
370
405
|
return resolutionResult;
|
|
371
406
|
} catch (error) {
|
|
372
407
|
if (!(error instanceof import_core5.OpenFeatureError)) {
|
|
373
|
-
throw new import_core5.GeneralError(error
|
|
408
|
+
throw new import_core5.GeneralError((error == null ? void 0 : error.message) || "unknown error");
|
|
374
409
|
}
|
|
375
410
|
throw error;
|
|
376
411
|
}
|
|
377
412
|
}
|
|
378
413
|
lookupFlagValue(flagKey, ctx) {
|
|
414
|
+
var _a;
|
|
379
415
|
const flagSpec = this._flagConfiguration[flagKey];
|
|
380
|
-
const isContextEval = ctx && flagSpec
|
|
381
|
-
const variant = isContextEval ? flagSpec.contextEvaluator
|
|
382
|
-
const value = variant && flagSpec
|
|
416
|
+
const isContextEval = ctx && (flagSpec == null ? void 0 : flagSpec.contextEvaluator);
|
|
417
|
+
const variant = isContextEval ? (_a = flagSpec.contextEvaluator) == null ? void 0 : _a.call(flagSpec, ctx) : flagSpec.defaultVariant;
|
|
418
|
+
const value = variant && (flagSpec == null ? void 0 : flagSpec.variants[variant]);
|
|
383
419
|
const reason = isContextEval ? import_core5.StandardResolutionReasons.TARGETING_MATCH : import_core5.StandardResolutionReasons.STATIC;
|
|
384
|
-
return {
|
|
385
|
-
value
|
|
386
|
-
|
|
420
|
+
return __spreadProps(__spreadValues({
|
|
421
|
+
value
|
|
422
|
+
}, variant && { variant }), {
|
|
387
423
|
reason
|
|
388
|
-
};
|
|
424
|
+
});
|
|
389
425
|
}
|
|
390
426
|
};
|
|
391
427
|
|
|
392
428
|
// src/open-feature.ts
|
|
393
|
-
var
|
|
394
|
-
var _globalThis = globalThis;
|
|
395
|
-
var OpenFeatureAPI = class _OpenFeatureAPI extends import_core6.OpenFeatureCommonAPI {
|
|
396
|
-
_statusEnumType = import_core3.ClientProviderStatus;
|
|
397
|
-
_apiEmitter = new OpenFeatureEventEmitter();
|
|
398
|
-
_defaultProvider = new import_core6.ProviderWrapper(NOOP_PROVIDER, import_core3.ClientProviderStatus.NOT_READY, this._statusEnumType);
|
|
399
|
-
_domainScopedProviders = /* @__PURE__ */ new Map();
|
|
400
|
-
_createEventEmitter = () => new OpenFeatureEventEmitter();
|
|
401
|
-
constructor() {
|
|
402
|
-
super("client");
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Gets a singleton instance of the OpenFeature API.
|
|
406
|
-
* @ignore
|
|
407
|
-
* @returns {OpenFeatureAPI} OpenFeature API
|
|
408
|
-
*/
|
|
409
|
-
static getInstance() {
|
|
410
|
-
const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];
|
|
411
|
-
if (globalApi) {
|
|
412
|
-
return globalApi;
|
|
413
|
-
}
|
|
414
|
-
const instance = new _OpenFeatureAPI();
|
|
415
|
-
_globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
|
|
416
|
-
return instance;
|
|
417
|
-
}
|
|
418
|
-
getProviderStatus(domain) {
|
|
419
|
-
if (!domain) {
|
|
420
|
-
return this._defaultProvider.status;
|
|
421
|
-
}
|
|
422
|
-
return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;
|
|
423
|
-
}
|
|
424
|
-
async setContext(domainOrContext, contextOrUndefined) {
|
|
425
|
-
const domain = (0, import_core6.stringOrUndefined)(domainOrContext);
|
|
426
|
-
const context = (0, import_core6.objectOrUndefined)(domainOrContext) ?? (0, import_core6.objectOrUndefined)(contextOrUndefined) ?? {};
|
|
427
|
-
if (domain) {
|
|
428
|
-
const wrapper = this._domainScopedProviders.get(domain);
|
|
429
|
-
if (wrapper) {
|
|
430
|
-
const oldContext = this.getContext(domain);
|
|
431
|
-
this._domainScopedContext.set(domain, context);
|
|
432
|
-
await this.runProviderContextChangeHandler(domain, wrapper, oldContext, context);
|
|
433
|
-
} else {
|
|
434
|
-
this._domainScopedContext.set(domain, context);
|
|
435
|
-
}
|
|
436
|
-
} else {
|
|
437
|
-
const oldContext = this._context;
|
|
438
|
-
this._context = context;
|
|
439
|
-
const unboundProviders = Array.from(this._domainScopedProviders.entries()).filter(([domain2]) => !this._domainScopedContext.has(domain2)).reduce((acc, [domain2, wrapper]) => {
|
|
440
|
-
acc.push({ domain: domain2, wrapper });
|
|
441
|
-
return acc;
|
|
442
|
-
}, []);
|
|
443
|
-
const allDomainRecords = [
|
|
444
|
-
// add in the default (no domain)
|
|
445
|
-
{ domain: void 0, wrapper: this._defaultProvider },
|
|
446
|
-
...unboundProviders
|
|
447
|
-
];
|
|
448
|
-
await Promise.all(
|
|
449
|
-
allDomainRecords.map(
|
|
450
|
-
(dm) => this.runProviderContextChangeHandler(dm.domain, dm.wrapper, oldContext, context)
|
|
451
|
-
)
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
getContext(domainOrUndefined) {
|
|
456
|
-
const domain = (0, import_core6.stringOrUndefined)(domainOrUndefined);
|
|
457
|
-
if (domain) {
|
|
458
|
-
const context = this._domainScopedContext.get(domain);
|
|
459
|
-
if (context) {
|
|
460
|
-
return context;
|
|
461
|
-
} else {
|
|
462
|
-
this._logger.debug(`Unable to find context for '${domain}'.`);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
return this._context;
|
|
466
|
-
}
|
|
467
|
-
async clearContext(domainOrUndefined) {
|
|
468
|
-
const domain = (0, import_core6.stringOrUndefined)(domainOrUndefined);
|
|
469
|
-
if (domain) {
|
|
470
|
-
const wrapper = this._domainScopedProviders.get(domain);
|
|
471
|
-
if (wrapper) {
|
|
472
|
-
const oldContext = this.getContext(domain);
|
|
473
|
-
this._domainScopedContext.delete(domain);
|
|
474
|
-
const newContext = this.getContext();
|
|
475
|
-
await this.runProviderContextChangeHandler(domain, wrapper, oldContext, newContext);
|
|
476
|
-
} else {
|
|
477
|
-
this._domainScopedContext.delete(domain);
|
|
478
|
-
}
|
|
479
|
-
} else {
|
|
480
|
-
return this.setContext({});
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Resets the global evaluation context and removes the evaluation context for
|
|
485
|
-
* all domains.
|
|
486
|
-
*/
|
|
487
|
-
async clearContexts() {
|
|
488
|
-
await this.clearContext();
|
|
489
|
-
await Promise.allSettled(Array.from(this._domainScopedProviders.keys()).map((domain) => this.clearContext(domain)));
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* A factory function for creating new named OpenFeature clients. Clients can contain
|
|
493
|
-
* their own state (e.g. logger, hook, context). Multiple clients can be used
|
|
494
|
-
* to segment feature flag configuration.
|
|
495
|
-
*
|
|
496
|
-
* If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.
|
|
497
|
-
* Otherwise, the default provider is used until a provider is assigned to that name.
|
|
498
|
-
* @param {string} domain An identifier which logically binds clients with providers
|
|
499
|
-
* @param {string} version The version of the client (only used for metadata)
|
|
500
|
-
* @returns {Client} OpenFeature Client
|
|
501
|
-
*/
|
|
502
|
-
getClient(domain, version) {
|
|
503
|
-
return new OpenFeatureClient(
|
|
504
|
-
// functions are passed here to make sure that these values are always up to date,
|
|
505
|
-
// and so we don't have to make these public properties on the API class.
|
|
506
|
-
() => this.getProviderForClient(domain),
|
|
507
|
-
() => this.getProviderStatus(domain),
|
|
508
|
-
() => this.buildAndCacheEventEmitterForClient(domain),
|
|
509
|
-
() => this._logger,
|
|
510
|
-
{ domain, version }
|
|
511
|
-
);
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Clears all registered providers and resets the default provider.
|
|
515
|
-
* @returns {Promise<void>}
|
|
516
|
-
*/
|
|
517
|
-
async clearProviders() {
|
|
518
|
-
await super.clearProvidersAndSetDefault(NOOP_PROVIDER);
|
|
519
|
-
this._domainScopedContext.clear();
|
|
520
|
-
}
|
|
521
|
-
async runProviderContextChangeHandler(domain, wrapper, oldContext, newContext) {
|
|
522
|
-
const providerName = wrapper.provider?.metadata?.name || "unnamed-provider";
|
|
523
|
-
try {
|
|
524
|
-
if (typeof wrapper.provider.onContextChange === "function") {
|
|
525
|
-
wrapper.incrementPendingContextChanges();
|
|
526
|
-
wrapper.status = this._statusEnumType.RECONCILING;
|
|
527
|
-
this.getAssociatedEventEmitters(domain).forEach((emitter) => {
|
|
528
|
-
emitter?.emit(import_core2.ClientProviderEvents.Reconciling, { domain, providerName });
|
|
529
|
-
});
|
|
530
|
-
this._apiEmitter?.emit(import_core2.ClientProviderEvents.Reconciling, { domain, providerName });
|
|
531
|
-
await wrapper.provider.onContextChange(oldContext, newContext);
|
|
532
|
-
wrapper.decrementPendingContextChanges();
|
|
533
|
-
}
|
|
534
|
-
wrapper.status = this._statusEnumType.READY;
|
|
535
|
-
if (wrapper.allContextChangesSettled) {
|
|
536
|
-
this.getAssociatedEventEmitters(domain).forEach((emitter) => {
|
|
537
|
-
emitter?.emit(import_core2.ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
|
|
538
|
-
});
|
|
539
|
-
this._apiEmitter?.emit(import_core2.ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
|
|
540
|
-
}
|
|
541
|
-
} catch (err) {
|
|
542
|
-
wrapper.decrementPendingContextChanges();
|
|
543
|
-
wrapper.status = this._statusEnumType.ERROR;
|
|
544
|
-
if (wrapper.allContextChangesSettled) {
|
|
545
|
-
const error = err;
|
|
546
|
-
const message = `Error running ${providerName}'s context change handler: ${error?.message}`;
|
|
547
|
-
this._logger?.error(`${message}`, err);
|
|
548
|
-
this.getAssociatedEventEmitters(domain).forEach((emitter) => {
|
|
549
|
-
emitter?.emit(import_core2.ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
|
|
550
|
-
});
|
|
551
|
-
this._apiEmitter?.emit(import_core2.ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
};
|
|
556
|
-
var OpenFeature = OpenFeatureAPI.getInstance();
|
|
429
|
+
var import_core7 = require("@openfeature/core");
|
|
557
430
|
|
|
558
|
-
// src/client/open-feature-client.ts
|
|
431
|
+
// src/client/internal/open-feature-client.ts
|
|
432
|
+
var import_core6 = require("@openfeature/core");
|
|
559
433
|
var OpenFeatureClient = class {
|
|
560
434
|
constructor(providerAccessor, providerStatusAccessor, emitterAccessor, globalLogger, options) {
|
|
561
435
|
this.providerAccessor = providerAccessor;
|
|
@@ -563,14 +437,14 @@ var OpenFeatureClient = class {
|
|
|
563
437
|
this.emitterAccessor = emitterAccessor;
|
|
564
438
|
this.globalLogger = globalLogger;
|
|
565
439
|
this.options = options;
|
|
440
|
+
this._hooks = [];
|
|
566
441
|
}
|
|
567
|
-
_hooks = [];
|
|
568
|
-
_clientLogger;
|
|
569
442
|
get metadata() {
|
|
443
|
+
var _a, _b;
|
|
570
444
|
return {
|
|
571
445
|
// Use domain if name is not provided
|
|
572
|
-
name: this.options.domain
|
|
573
|
-
domain: this.options.domain
|
|
446
|
+
name: (_a = this.options.domain) != null ? _a : this.options.name,
|
|
447
|
+
domain: (_b = this.options.domain) != null ? _b : this.options.name,
|
|
574
448
|
version: this.options.version,
|
|
575
449
|
providerMetadata: this.providerAccessor().metadata
|
|
576
450
|
};
|
|
@@ -579,8 +453,9 @@ var OpenFeatureClient = class {
|
|
|
579
453
|
return this.providerStatusAccessor();
|
|
580
454
|
}
|
|
581
455
|
addHandler(eventType, handler) {
|
|
456
|
+
var _a;
|
|
582
457
|
this.emitterAccessor().addHandler(eventType, handler);
|
|
583
|
-
const shouldRunNow = (0,
|
|
458
|
+
const shouldRunNow = (0, import_core6.statusMatchesEvent)(eventType, this.providerStatus);
|
|
584
459
|
if (shouldRunNow) {
|
|
585
460
|
try {
|
|
586
461
|
handler({
|
|
@@ -589,7 +464,7 @@ var OpenFeatureClient = class {
|
|
|
589
464
|
providerName: this._provider.metadata.name
|
|
590
465
|
});
|
|
591
466
|
} catch (err) {
|
|
592
|
-
this._logger
|
|
467
|
+
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
|
|
593
468
|
}
|
|
594
469
|
}
|
|
595
470
|
}
|
|
@@ -600,7 +475,7 @@ var OpenFeatureClient = class {
|
|
|
600
475
|
return this.emitterAccessor().getHandlers(eventType);
|
|
601
476
|
}
|
|
602
477
|
setLogger(logger) {
|
|
603
|
-
this._clientLogger = new
|
|
478
|
+
this._clientLogger = new import_core6.SafeLogger(logger);
|
|
604
479
|
return this;
|
|
605
480
|
}
|
|
606
481
|
addHooks(...hooks) {
|
|
@@ -653,6 +528,7 @@ var OpenFeatureClient = class {
|
|
|
653
528
|
return this.evaluate(flagKey, this._provider.resolveObjectEvaluation, defaultValue, "object", options);
|
|
654
529
|
}
|
|
655
530
|
evaluate(flagKey, resolver, defaultValue, flagType, options = {}) {
|
|
531
|
+
var _a, _b;
|
|
656
532
|
const allHooks = [
|
|
657
533
|
...OpenFeature.getHooks(),
|
|
658
534
|
...this.getHooks(),
|
|
@@ -660,9 +536,7 @@ var OpenFeatureClient = class {
|
|
|
660
536
|
...this._provider.hooks || []
|
|
661
537
|
];
|
|
662
538
|
const allHooksReversed = [...allHooks].reverse();
|
|
663
|
-
const context = {
|
|
664
|
-
...OpenFeature.getContext(this?.options?.domain)
|
|
665
|
-
};
|
|
539
|
+
const context = __spreadValues({}, OpenFeature.getContext((_a = this == null ? void 0 : this.options) == null ? void 0 : _a.domain));
|
|
666
540
|
const hookContext = {
|
|
667
541
|
flagKey,
|
|
668
542
|
defaultValue,
|
|
@@ -674,28 +548,30 @@ var OpenFeatureClient = class {
|
|
|
674
548
|
};
|
|
675
549
|
try {
|
|
676
550
|
this.beforeHooks(allHooks, hookContext, options);
|
|
677
|
-
if (this.providerStatus ===
|
|
678
|
-
throw new
|
|
679
|
-
} else if (this.providerStatus ===
|
|
680
|
-
throw new
|
|
551
|
+
if (this.providerStatus === import_core.ClientProviderStatus.NOT_READY) {
|
|
552
|
+
throw new import_core6.ProviderNotReadyError("provider has not yet initialized");
|
|
553
|
+
} else if (this.providerStatus === import_core.ClientProviderStatus.FATAL) {
|
|
554
|
+
throw new import_core6.ProviderFatalError("provider is in an irrecoverable error state");
|
|
681
555
|
}
|
|
682
556
|
const resolution = resolver.call(this._provider, flagKey, defaultValue, context, this._logger);
|
|
683
|
-
const evaluationDetails = {
|
|
684
|
-
|
|
685
|
-
flagMetadata: Object.freeze(resolution.flagMetadata ?? {}),
|
|
557
|
+
const evaluationDetails = __spreadProps(__spreadValues({}, resolution), {
|
|
558
|
+
flagMetadata: Object.freeze((_b = resolution.flagMetadata) != null ? _b : {}),
|
|
686
559
|
flagKey
|
|
687
|
-
};
|
|
560
|
+
});
|
|
561
|
+
if (evaluationDetails.errorCode) {
|
|
562
|
+
throw (0, import_core6.instantiateErrorByErrorCode)(evaluationDetails.errorCode);
|
|
563
|
+
}
|
|
688
564
|
this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
|
|
689
565
|
return evaluationDetails;
|
|
690
566
|
} catch (err) {
|
|
691
|
-
const errorMessage = err
|
|
692
|
-
const errorCode = err
|
|
567
|
+
const errorMessage = err == null ? void 0 : err.message;
|
|
568
|
+
const errorCode = (err == null ? void 0 : err.code) || import_core6.ErrorCode.GENERAL;
|
|
693
569
|
this.errorHooks(allHooksReversed, hookContext, err, options);
|
|
694
570
|
return {
|
|
695
571
|
errorCode,
|
|
696
572
|
errorMessage,
|
|
697
573
|
value: defaultValue,
|
|
698
|
-
reason:
|
|
574
|
+
reason: import_core6.StandardResolutionReasons.ERROR,
|
|
699
575
|
flagMetadata: Object.freeze({}),
|
|
700
576
|
flagKey
|
|
701
577
|
};
|
|
@@ -704,40 +580,44 @@ var OpenFeatureClient = class {
|
|
|
704
580
|
}
|
|
705
581
|
}
|
|
706
582
|
beforeHooks(hooks, hookContext, options) {
|
|
583
|
+
var _a;
|
|
707
584
|
Object.freeze(hookContext);
|
|
708
585
|
Object.freeze(hookContext.context);
|
|
709
586
|
for (const hook of hooks) {
|
|
710
|
-
hook
|
|
587
|
+
(_a = hook == null ? void 0 : hook.before) == null ? void 0 : _a.call(hook, hookContext, Object.freeze(options.hookHints));
|
|
711
588
|
}
|
|
712
589
|
}
|
|
713
590
|
afterHooks(hooks, hookContext, evaluationDetails, options) {
|
|
591
|
+
var _a;
|
|
714
592
|
for (const hook of hooks) {
|
|
715
|
-
hook
|
|
593
|
+
(_a = hook == null ? void 0 : hook.after) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, options.hookHints);
|
|
716
594
|
}
|
|
717
595
|
}
|
|
718
596
|
errorHooks(hooks, hookContext, err, options) {
|
|
597
|
+
var _a;
|
|
719
598
|
for (const hook of hooks) {
|
|
720
599
|
try {
|
|
721
|
-
hook
|
|
600
|
+
(_a = hook == null ? void 0 : hook.error) == null ? void 0 : _a.call(hook, hookContext, err, options.hookHints);
|
|
722
601
|
} catch (err2) {
|
|
723
602
|
this._logger.error(`Unhandled error during 'error' hook: ${err2}`);
|
|
724
603
|
if (err2 instanceof Error) {
|
|
725
604
|
this._logger.error(err2.stack);
|
|
726
605
|
}
|
|
727
|
-
this._logger.error(err2
|
|
606
|
+
this._logger.error(err2 == null ? void 0 : err2.stack);
|
|
728
607
|
}
|
|
729
608
|
}
|
|
730
609
|
}
|
|
731
610
|
finallyHooks(hooks, hookContext, options) {
|
|
611
|
+
var _a;
|
|
732
612
|
for (const hook of hooks) {
|
|
733
613
|
try {
|
|
734
|
-
hook
|
|
614
|
+
(_a = hook == null ? void 0 : hook.finally) == null ? void 0 : _a.call(hook, hookContext, options.hookHints);
|
|
735
615
|
} catch (err) {
|
|
736
616
|
this._logger.error(`Unhandled error during 'finally' hook: ${err}`);
|
|
737
617
|
if (err instanceof Error) {
|
|
738
618
|
this._logger.error(err.stack);
|
|
739
619
|
}
|
|
740
|
-
this._logger.error(err
|
|
620
|
+
this._logger.error(err == null ? void 0 : err.stack);
|
|
741
621
|
}
|
|
742
622
|
}
|
|
743
623
|
}
|
|
@@ -749,6 +629,222 @@ var OpenFeatureClient = class {
|
|
|
749
629
|
}
|
|
750
630
|
};
|
|
751
631
|
|
|
632
|
+
// src/open-feature.ts
|
|
633
|
+
var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/web-sdk/api");
|
|
634
|
+
var _globalThis = globalThis;
|
|
635
|
+
var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommonAPI {
|
|
636
|
+
constructor() {
|
|
637
|
+
super("client");
|
|
638
|
+
this._statusEnumType = import_core.ClientProviderStatus;
|
|
639
|
+
this._apiEmitter = new OpenFeatureEventEmitter();
|
|
640
|
+
this._defaultProvider = new import_core7.ProviderWrapper(
|
|
641
|
+
NOOP_PROVIDER,
|
|
642
|
+
import_core.ClientProviderStatus.NOT_READY,
|
|
643
|
+
this._statusEnumType
|
|
644
|
+
);
|
|
645
|
+
this._domainScopedProviders = /* @__PURE__ */ new Map();
|
|
646
|
+
this._createEventEmitter = () => new OpenFeatureEventEmitter();
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Gets a singleton instance of the OpenFeature API.
|
|
650
|
+
* @ignore
|
|
651
|
+
* @returns {OpenFeatureAPI} OpenFeature API
|
|
652
|
+
*/
|
|
653
|
+
static getInstance() {
|
|
654
|
+
const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];
|
|
655
|
+
if (globalApi) {
|
|
656
|
+
return globalApi;
|
|
657
|
+
}
|
|
658
|
+
const instance = new _OpenFeatureAPI();
|
|
659
|
+
_globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
|
|
660
|
+
return instance;
|
|
661
|
+
}
|
|
662
|
+
getProviderStatus(domain) {
|
|
663
|
+
var _a, _b;
|
|
664
|
+
if (!domain) {
|
|
665
|
+
return this._defaultProvider.status;
|
|
666
|
+
}
|
|
667
|
+
return (_b = (_a = this._domainScopedProviders.get(domain)) == null ? void 0 : _a.status) != null ? _b : this._defaultProvider.status;
|
|
668
|
+
}
|
|
669
|
+
setProviderAndWait(clientOrProvider, providerContextOrUndefined, contextOrUndefined) {
|
|
670
|
+
return __async(this, null, function* () {
|
|
671
|
+
const domain = (0, import_core7.stringOrUndefined)(clientOrProvider);
|
|
672
|
+
const provider = domain ? (0, import_core7.objectOrUndefined)(providerContextOrUndefined) : (0, import_core7.objectOrUndefined)(clientOrProvider);
|
|
673
|
+
const context = domain ? (0, import_core7.objectOrUndefined)(contextOrUndefined) : (0, import_core7.objectOrUndefined)(providerContextOrUndefined);
|
|
674
|
+
if (context) {
|
|
675
|
+
if (domain) {
|
|
676
|
+
this._domainScopedContext.set(domain, context);
|
|
677
|
+
} else {
|
|
678
|
+
this._context = context;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
yield this.setAwaitableProvider(domain, provider);
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
setProvider(domainOrProvider, providerContextOrUndefined, contextOrUndefined) {
|
|
685
|
+
const domain = (0, import_core7.stringOrUndefined)(domainOrProvider);
|
|
686
|
+
const provider = domain ? (0, import_core7.objectOrUndefined)(providerContextOrUndefined) : (0, import_core7.objectOrUndefined)(domainOrProvider);
|
|
687
|
+
const context = domain ? (0, import_core7.objectOrUndefined)(contextOrUndefined) : (0, import_core7.objectOrUndefined)(providerContextOrUndefined);
|
|
688
|
+
if (context) {
|
|
689
|
+
if (domain) {
|
|
690
|
+
this._domainScopedContext.set(domain, context);
|
|
691
|
+
} else {
|
|
692
|
+
this._context = context;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
const maybePromise = this.setAwaitableProvider(domain, provider);
|
|
696
|
+
Promise.resolve(maybePromise).catch((err) => {
|
|
697
|
+
this._logger.error("Error during provider initialization:", err);
|
|
698
|
+
});
|
|
699
|
+
return this;
|
|
700
|
+
}
|
|
701
|
+
setContext(domainOrContext, contextOrUndefined) {
|
|
702
|
+
return __async(this, null, function* () {
|
|
703
|
+
var _a, _b;
|
|
704
|
+
const domain = (0, import_core7.stringOrUndefined)(domainOrContext);
|
|
705
|
+
const context = (_b = (_a = (0, import_core7.objectOrUndefined)(domainOrContext)) != null ? _a : (0, import_core7.objectOrUndefined)(contextOrUndefined)) != null ? _b : {};
|
|
706
|
+
if (domain) {
|
|
707
|
+
const wrapper = this._domainScopedProviders.get(domain);
|
|
708
|
+
if (wrapper) {
|
|
709
|
+
const oldContext = this.getContext(domain);
|
|
710
|
+
this._domainScopedContext.set(domain, context);
|
|
711
|
+
yield this.runProviderContextChangeHandler(domain, wrapper, oldContext, context);
|
|
712
|
+
} else {
|
|
713
|
+
this._domainScopedContext.set(domain, context);
|
|
714
|
+
}
|
|
715
|
+
} else {
|
|
716
|
+
const oldContext = this._context;
|
|
717
|
+
this._context = context;
|
|
718
|
+
const unboundProviders = Array.from(this._domainScopedProviders.entries()).filter(([domain2]) => !this._domainScopedContext.has(domain2)).reduce((acc, [domain2, wrapper]) => {
|
|
719
|
+
acc.push({ domain: domain2, wrapper });
|
|
720
|
+
return acc;
|
|
721
|
+
}, []);
|
|
722
|
+
const allDomainRecords = [
|
|
723
|
+
// add in the default (no domain)
|
|
724
|
+
{ domain: void 0, wrapper: this._defaultProvider },
|
|
725
|
+
...unboundProviders
|
|
726
|
+
];
|
|
727
|
+
yield Promise.all(
|
|
728
|
+
allDomainRecords.map((dm) => this.runProviderContextChangeHandler(dm.domain, dm.wrapper, oldContext, context))
|
|
729
|
+
);
|
|
730
|
+
}
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
getContext(domainOrUndefined) {
|
|
734
|
+
const domain = (0, import_core7.stringOrUndefined)(domainOrUndefined);
|
|
735
|
+
if (domain) {
|
|
736
|
+
const context = this._domainScopedContext.get(domain);
|
|
737
|
+
if (context) {
|
|
738
|
+
return context;
|
|
739
|
+
} else {
|
|
740
|
+
this._logger.debug(`Unable to find context for '${domain}'.`);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
return this._context;
|
|
744
|
+
}
|
|
745
|
+
clearContext(domainOrUndefined) {
|
|
746
|
+
return __async(this, null, function* () {
|
|
747
|
+
const domain = (0, import_core7.stringOrUndefined)(domainOrUndefined);
|
|
748
|
+
if (domain) {
|
|
749
|
+
const wrapper = this._domainScopedProviders.get(domain);
|
|
750
|
+
if (wrapper) {
|
|
751
|
+
const oldContext = this.getContext(domain);
|
|
752
|
+
this._domainScopedContext.delete(domain);
|
|
753
|
+
const newContext = this.getContext();
|
|
754
|
+
yield this.runProviderContextChangeHandler(domain, wrapper, oldContext, newContext);
|
|
755
|
+
} else {
|
|
756
|
+
this._domainScopedContext.delete(domain);
|
|
757
|
+
}
|
|
758
|
+
} else {
|
|
759
|
+
return this.setContext({});
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Resets the global evaluation context and removes the evaluation context for
|
|
765
|
+
* all domains.
|
|
766
|
+
*/
|
|
767
|
+
clearContexts() {
|
|
768
|
+
return __async(this, null, function* () {
|
|
769
|
+
yield this.clearContext();
|
|
770
|
+
yield Promise.allSettled(Array.from(this._domainScopedProviders.keys()).map((domain) => this.clearContext(domain)));
|
|
771
|
+
});
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* A factory function for creating new named OpenFeature clients. Clients can contain
|
|
775
|
+
* their own state (e.g. logger, hook, context). Multiple clients can be used
|
|
776
|
+
* to segment feature flag configuration.
|
|
777
|
+
*
|
|
778
|
+
* If there is already a provider bound to this name via {@link this.setProvider setProvider}, this provider will be used.
|
|
779
|
+
* Otherwise, the default provider is used until a provider is assigned to that name.
|
|
780
|
+
* @param {string} domain An identifier which logically binds clients with providers
|
|
781
|
+
* @param {string} version The version of the client (only used for metadata)
|
|
782
|
+
* @returns {Client} OpenFeature Client
|
|
783
|
+
*/
|
|
784
|
+
getClient(domain, version) {
|
|
785
|
+
return new OpenFeatureClient(
|
|
786
|
+
// functions are passed here to make sure that these values are always up to date,
|
|
787
|
+
// and so we don't have to make these public properties on the API class.
|
|
788
|
+
() => this.getProviderForClient(domain),
|
|
789
|
+
() => this.getProviderStatus(domain),
|
|
790
|
+
() => this.buildAndCacheEventEmitterForClient(domain),
|
|
791
|
+
() => this._logger,
|
|
792
|
+
{ domain, version }
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Clears all registered providers and resets the default provider.
|
|
797
|
+
* @returns {Promise<void>}
|
|
798
|
+
*/
|
|
799
|
+
clearProviders() {
|
|
800
|
+
return __async(this, null, function* () {
|
|
801
|
+
yield __superGet(_OpenFeatureAPI.prototype, this, "clearProvidersAndSetDefault").call(this, NOOP_PROVIDER);
|
|
802
|
+
this._domainScopedContext.clear();
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
runProviderContextChangeHandler(domain, wrapper, oldContext, newContext) {
|
|
806
|
+
return __async(this, null, function* () {
|
|
807
|
+
var _a, _b, _c, _d, _e, _f;
|
|
808
|
+
const providerName = ((_b = (_a = wrapper.provider) == null ? void 0 : _a.metadata) == null ? void 0 : _b.name) || "unnamed-provider";
|
|
809
|
+
try {
|
|
810
|
+
if (typeof wrapper.provider.onContextChange === "function") {
|
|
811
|
+
const maybePromise = wrapper.provider.onContextChange(oldContext, newContext);
|
|
812
|
+
if (typeof (maybePromise == null ? void 0 : maybePromise.then) === "function") {
|
|
813
|
+
wrapper.incrementPendingContextChanges();
|
|
814
|
+
wrapper.status = this._statusEnumType.RECONCILING;
|
|
815
|
+
this.getAssociatedEventEmitters(domain).forEach((emitter) => {
|
|
816
|
+
emitter == null ? void 0 : emitter.emit(import_core3.ClientProviderEvents.Reconciling, { domain, providerName });
|
|
817
|
+
});
|
|
818
|
+
(_c = this._apiEmitter) == null ? void 0 : _c.emit(import_core3.ClientProviderEvents.Reconciling, { domain, providerName });
|
|
819
|
+
yield maybePromise;
|
|
820
|
+
wrapper.decrementPendingContextChanges();
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
wrapper.status = this._statusEnumType.READY;
|
|
824
|
+
if (wrapper.allContextChangesSettled) {
|
|
825
|
+
this.getAssociatedEventEmitters(domain).forEach((emitter) => {
|
|
826
|
+
emitter == null ? void 0 : emitter.emit(import_core3.ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
|
|
827
|
+
});
|
|
828
|
+
(_d = this._apiEmitter) == null ? void 0 : _d.emit(import_core3.ClientProviderEvents.ContextChanged, { clientName: domain, domain, providerName });
|
|
829
|
+
}
|
|
830
|
+
} catch (err) {
|
|
831
|
+
wrapper.decrementPendingContextChanges();
|
|
832
|
+
wrapper.status = this._statusEnumType.ERROR;
|
|
833
|
+
if (wrapper.allContextChangesSettled) {
|
|
834
|
+
const error = err;
|
|
835
|
+
const message = `Error running ${providerName}'s context change handler: ${error == null ? void 0 : error.message}`;
|
|
836
|
+
(_e = this._logger) == null ? void 0 : _e.error(`${message}`, err);
|
|
837
|
+
this.getAssociatedEventEmitters(domain).forEach((emitter) => {
|
|
838
|
+
emitter == null ? void 0 : emitter.emit(import_core3.ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
|
|
839
|
+
});
|
|
840
|
+
(_f = this._apiEmitter) == null ? void 0 : _f.emit(import_core3.ClientProviderEvents.Error, { clientName: domain, domain, providerName, message });
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
var OpenFeature = OpenFeatureAPI.getInstance();
|
|
847
|
+
|
|
752
848
|
// src/index.ts
|
|
753
849
|
__reExport(src_exports, require("@openfeature/core"), module.exports);
|
|
754
850
|
//# sourceMappingURL=index.js.map
|