@configdirector/react-native-sdk 1.9.1 → 1.10.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/dist/configdirector-react-native-testing.d.mts +1 -1
- package/dist/configdirector-react-native-testing.mjs +2 -2
- package/dist/configdirector-react-native.d.mts +2 -2
- package/dist/configdirector-react-native.mjs +41 -38
- package/dist/{installedTestClient-CNYgzQuj.mjs → installedTestClient-BaCuY_Ru.mjs} +63 -40
- package/dist/{types-BBQmjjf5.d.mts → types-DmbDeZqL.d.mts} +28 -7
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as NativeJsonValue, d as ConfigDirectorContext, i as ConfigDirectorClient, l as NativeValue, p as ConfigDirectorLogger, u as NativeValues } from "./types-
|
|
1
|
+
import { c as NativeJsonValue, d as ConfigDirectorContext, i as ConfigDirectorClient, l as NativeValue, p as ConfigDirectorLogger, u as NativeValues } from "./types-DmbDeZqL.mjs";
|
|
2
2
|
|
|
3
3
|
//#region ../shared/src/errors.d.ts
|
|
4
4
|
declare class ConfigDirectorConnectionError extends Error {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as createDefaultLogger, d as ConfigDirectorConnectionError, f as ConfigDirectorValidationError, l as nativeValueConfigState, m as _defineProperty, p as Emitter, r as DefaultConfigDirectorClient, s as discardingTelemetryClient, t as INSTALLED_TEST_CLIENT_SLOT } from "./installedTestClient-
|
|
1
|
+
import { c as createDefaultLogger, d as ConfigDirectorConnectionError, f as ConfigDirectorValidationError, l as nativeValueConfigState, m as _defineProperty, p as Emitter, r as DefaultConfigDirectorClient, s as discardingTelemetryClient, t as INSTALLED_TEST_CLIENT_SLOT } from "./installedTestClient-BaCuY_Ru.mjs";
|
|
2
2
|
//#region ../js-client-core/src/testing/InMemoryConnection.ts
|
|
3
3
|
const TEST_ENVIRONMENT = {
|
|
4
4
|
environmentId: "test-environment",
|
|
@@ -295,7 +295,7 @@ const installTestClient = (testClient) => {
|
|
|
295
295
|
const createTestClient = (options) => {
|
|
296
296
|
return createTestClient$1({
|
|
297
297
|
sdkName: "react-native-sdk",
|
|
298
|
-
sdkVersion: "1.
|
|
298
|
+
sdkVersion: "1.10.0"
|
|
299
299
|
}, options);
|
|
300
300
|
};
|
|
301
301
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ConfigDirectorClientOptions, d as ConfigDirectorContext, f as ConfigDirectorLogMessageDecorator, g as
|
|
1
|
+
import { _ as ConnectionMode, a as ConfigDirectorClientOptions, d as ConfigDirectorContext, f as ConfigDirectorLogMessageDecorator, g as ConfigValueType, h as ConfigEvaluation, i as ConfigDirectorClient, m as ConfigDirectorLoggingLevel, n as CachingProvider, o as OfflineValue, p as ConfigDirectorLogger, r as ClientHooks, s as OfflineValues, t as CachingOptions, v as EvaluationReason } from "./types-DmbDeZqL.mjs";
|
|
2
2
|
import { Component, PropsWithChildren } from "react";
|
|
3
3
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
4
|
|
|
@@ -151,4 +151,4 @@ declare class ConfigDirectorReactContextError extends Error {
|
|
|
151
151
|
//#region src/logger.d.ts
|
|
152
152
|
declare const createConsoleLogger: (level?: ConfigDirectorLoggingLevel) => DefaultConsoleLogger;
|
|
153
153
|
//#endregion
|
|
154
|
-
export { type CachingOptions, type CachingProvider, type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorProvider, type ConfigDirectorProviderClientProps, type ConfigDirectorProviderOptions, type ConfigDirectorProviderProps, ConfigDirectorReactContextError, type ConnectionMode, type NetInfoSubscribe, type OfflineValue, type OfflineValues, createClient, createConsoleLogger, useClient, useConfigValue, useContext };
|
|
154
|
+
export { type CachingOptions, type CachingProvider, type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorProvider, type ConfigDirectorProviderClientProps, type ConfigDirectorProviderOptions, type ConfigDirectorProviderProps, ConfigDirectorReactContextError, type ConfigEvaluation, type ConnectionMode, type EvaluationReason, type NetInfoSubscribe, type OfflineValue, type OfflineValues, createClient, createConsoleLogger, useClient, useConfigValue, useContext };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as DEFAULT_CACHING_SIZE_LIMIT_BYTES, c as createDefaultLogger, i as CACHED_VALUES_STORAGE_KEY_PREFIX, m as _defineProperty, n as readInstalledTestClient, o as fetchWithTimeout, r as DefaultConfigDirectorClient, u as isFetchErrorFatal } from "./installedTestClient-
|
|
1
|
+
import { a as DEFAULT_CACHING_SIZE_LIMIT_BYTES, c as createDefaultLogger, i as CACHED_VALUES_STORAGE_KEY_PREFIX, m as _defineProperty, n as readInstalledTestClient, o as fetchWithTimeout, r as DefaultConfigDirectorClient, u as isFetchErrorFatal } from "./installedTestClient-BaCuY_Ru.mjs";
|
|
2
2
|
import React, { Component, useContext as useContext$1 } from "react";
|
|
3
3
|
import { AppState, NativeModules } from "react-native";
|
|
4
4
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
@@ -542,6 +542,41 @@ const findAsyncStorage = (logger) => importAsyncStorage().then((lookup) => {
|
|
|
542
542
|
return lookup;
|
|
543
543
|
});
|
|
544
544
|
//#endregion
|
|
545
|
+
//#region src/cachingProvider.ts
|
|
546
|
+
const asyncStorageCachingProvider = (asyncStorage) => (clientSdkKeyDigest) => {
|
|
547
|
+
const storageKey = clientSdkKeyDigest.then((digest) => CACHED_VALUES_STORAGE_KEY_PREFIX + digest);
|
|
548
|
+
return {
|
|
549
|
+
read: async () => {
|
|
550
|
+
const lookup = await asyncStorage;
|
|
551
|
+
return lookup.outcome === "installed" ? lookup.storage.getItem(await storageKey) : void 0;
|
|
552
|
+
},
|
|
553
|
+
write: async (value) => {
|
|
554
|
+
const lookup = await asyncStorage;
|
|
555
|
+
if (lookup.outcome === "installed") await lookup.storage.setItem(await storageKey, value);
|
|
556
|
+
},
|
|
557
|
+
remove: async () => {
|
|
558
|
+
const lookup = await asyncStorage;
|
|
559
|
+
if (lookup.outcome === "installed") await lookup.storage.removeItem(await storageKey);
|
|
560
|
+
},
|
|
561
|
+
sizeLimit: () => DEFAULT_CACHING_SIZE_LIMIT_BYTES
|
|
562
|
+
};
|
|
563
|
+
};
|
|
564
|
+
//#endregion
|
|
565
|
+
//#region src/instanceIdStorage.ts
|
|
566
|
+
const asyncStorageInstanceIdStorage = (asyncStorage) => {
|
|
567
|
+
const installedAsyncStorage = async () => {
|
|
568
|
+
const lookup = await asyncStorage;
|
|
569
|
+
switch (lookup.outcome) {
|
|
570
|
+
case "installed": return lookup.storage;
|
|
571
|
+
case "not installed": throw new Error("@react-native-async-storage/async-storage is not installed");
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
return {
|
|
575
|
+
getItem: async (key) => (await installedAsyncStorage()).getItem(key),
|
|
576
|
+
setItem: async (key, value) => (await installedAsyncStorage()).setItem(key, value)
|
|
577
|
+
};
|
|
578
|
+
};
|
|
579
|
+
//#endregion
|
|
545
580
|
//#region src/utf8Encoder.ts
|
|
546
581
|
/**
|
|
547
582
|
* Encodes a string to a UTF-8 byte sequence.
|
|
@@ -582,42 +617,6 @@ const encodeManually = (str) => {
|
|
|
582
617
|
return new Uint8Array(bytes);
|
|
583
618
|
};
|
|
584
619
|
//#endregion
|
|
585
|
-
//#region src/cachingProvider.ts
|
|
586
|
-
const storageKeyFor = (clientSdkKey) => CACHED_VALUES_STORAGE_KEY_PREFIX + bytesToHex(sha256(encodeUtf8(clientSdkKey)));
|
|
587
|
-
const asyncStorageCachingProvider = (asyncStorage) => (clientSdkKey) => {
|
|
588
|
-
const storageKey = storageKeyFor(clientSdkKey);
|
|
589
|
-
return {
|
|
590
|
-
read: async () => {
|
|
591
|
-
const lookup = await asyncStorage;
|
|
592
|
-
return lookup.outcome === "installed" ? lookup.storage.getItem(storageKey) : void 0;
|
|
593
|
-
},
|
|
594
|
-
write: async (value) => {
|
|
595
|
-
const lookup = await asyncStorage;
|
|
596
|
-
if (lookup.outcome === "installed") await lookup.storage.setItem(storageKey, value);
|
|
597
|
-
},
|
|
598
|
-
remove: async () => {
|
|
599
|
-
const lookup = await asyncStorage;
|
|
600
|
-
if (lookup.outcome === "installed") await lookup.storage.removeItem(storageKey);
|
|
601
|
-
},
|
|
602
|
-
sizeLimit: () => DEFAULT_CACHING_SIZE_LIMIT_BYTES
|
|
603
|
-
};
|
|
604
|
-
};
|
|
605
|
-
//#endregion
|
|
606
|
-
//#region src/instanceIdStorage.ts
|
|
607
|
-
const asyncStorageInstanceIdStorage = (asyncStorage) => {
|
|
608
|
-
const installedAsyncStorage = async () => {
|
|
609
|
-
const lookup = await asyncStorage;
|
|
610
|
-
switch (lookup.outcome) {
|
|
611
|
-
case "installed": return lookup.storage;
|
|
612
|
-
case "not installed": throw new Error("@react-native-async-storage/async-storage is not installed");
|
|
613
|
-
}
|
|
614
|
-
};
|
|
615
|
-
return {
|
|
616
|
-
getItem: async (key) => (await installedAsyncStorage()).getItem(key),
|
|
617
|
-
setItem: async (key, value) => (await installedAsyncStorage()).setItem(key, value)
|
|
618
|
-
};
|
|
619
|
-
};
|
|
620
|
-
//#endregion
|
|
621
620
|
//#region src/reactNativeStreamingFetch.ts
|
|
622
621
|
const abortError = (message) => {
|
|
623
622
|
const err = new Error(message);
|
|
@@ -754,6 +753,9 @@ var ReactNativeTelemetryClient = class {
|
|
|
754
753
|
}
|
|
755
754
|
};
|
|
756
755
|
//#endregion
|
|
756
|
+
//#region src/sha256HexDigest.ts
|
|
757
|
+
const sha256HexDigest = (text) => Promise.resolve(bytesToHex(sha256(encodeUtf8(text))));
|
|
758
|
+
//#endregion
|
|
757
759
|
//#region src/url.ts
|
|
758
760
|
var MinimalUrl = class {
|
|
759
761
|
constructor(input, base) {
|
|
@@ -775,7 +777,7 @@ const createReactNativeClient = (clientSdkKey, clientOptions) => {
|
|
|
775
777
|
var _clientOptions$logger;
|
|
776
778
|
const sdkIdentity = {
|
|
777
779
|
sdkName: "react-native-sdk",
|
|
778
|
-
sdkVersion: "1.
|
|
780
|
+
sdkVersion: "1.10.0"
|
|
779
781
|
};
|
|
780
782
|
const logger = (_clientOptions$logger = clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.logger) !== null && _clientOptions$logger !== void 0 ? _clientOptions$logger : createConsoleLogger("warn");
|
|
781
783
|
const metadata = resolveMetadata(clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.metadata, logger);
|
|
@@ -796,6 +798,7 @@ const createReactNativeClient = (clientSdkKey, clientOptions) => {
|
|
|
796
798
|
fetch: reactNativeStreamingFetch,
|
|
797
799
|
urlFactory,
|
|
798
800
|
instanceIdStorage: asyncStorageInstanceIdStorage(asyncStorage),
|
|
801
|
+
sha256HexDigest,
|
|
799
802
|
platformCachingProvider: asyncStorageCachingProvider(asyncStorage)
|
|
800
803
|
});
|
|
801
804
|
};
|
|
@@ -875,9 +875,12 @@ const parseJson = (jsonString, defaultValue, requestedType, valueId) => {
|
|
|
875
875
|
};
|
|
876
876
|
const isJsonTypeCompatible = (parsed, defaultValue) => {
|
|
877
877
|
if (parsed === null) return false;
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
878
|
+
return jsonShapeOf(parsed) === jsonShapeOf(defaultValue);
|
|
879
|
+
};
|
|
880
|
+
const jsonShapeOf = (value) => {
|
|
881
|
+
if (Array.isArray(value)) return "array";
|
|
882
|
+
const nativeType = typeof value;
|
|
883
|
+
return nativeType === "bigint" ? "number" : nativeType;
|
|
881
884
|
};
|
|
882
885
|
//#endregion
|
|
883
886
|
//#region ../shared/src/logger.ts
|
|
@@ -1331,11 +1334,12 @@ const utf8ByteLength = (text) => {
|
|
|
1331
1334
|
};
|
|
1332
1335
|
//#endregion
|
|
1333
1336
|
//#region ../js-client-core/src/cached-values.ts
|
|
1334
|
-
const ENTRY_FORMAT_VERSION =
|
|
1337
|
+
const ENTRY_FORMAT_VERSION = 2;
|
|
1338
|
+
const FIRST_ENTRY_FORMAT_VERSION = 1;
|
|
1335
1339
|
const DEFAULT_CONTEXT_KIND = "user";
|
|
1336
1340
|
const CACHED_VALUES_STORAGE_KEY_PREFIX = "configdirector-sdk:cached-values:";
|
|
1337
1341
|
const DEFAULT_CACHING_SIZE_LIMIT_BYTES = 256 * 1024;
|
|
1338
|
-
const planCaching = (connectionPlan, caching,
|
|
1342
|
+
const planCaching = (connectionPlan, caching, sha256HexDigest, platformCachingProvider) => {
|
|
1339
1343
|
var _caching$provider;
|
|
1340
1344
|
if (connectionPlan.kind === "stay-offline") return {
|
|
1341
1345
|
kind: "no cache",
|
|
@@ -1345,7 +1349,12 @@ const planCaching = (connectionPlan, caching, platformProvider) => {
|
|
|
1345
1349
|
kind: "no cache",
|
|
1346
1350
|
reason: "turned off"
|
|
1347
1351
|
};
|
|
1348
|
-
|
|
1352
|
+
if (!sha256HexDigest) return {
|
|
1353
|
+
kind: "no cache",
|
|
1354
|
+
reason: "no SHA-256 available"
|
|
1355
|
+
};
|
|
1356
|
+
const clientSdkKeyDigest = sha256HexDigest(connectionPlan.clientSdkKey);
|
|
1357
|
+
const provider = (_caching$provider = caching === null || caching === void 0 ? void 0 : caching.provider) !== null && _caching$provider !== void 0 ? _caching$provider : platformCachingProvider === null || platformCachingProvider === void 0 ? void 0 : platformCachingProvider(clientSdkKeyDigest);
|
|
1349
1358
|
if (!provider) return {
|
|
1350
1359
|
kind: "no cache",
|
|
1351
1360
|
reason: "no provider available"
|
|
@@ -1353,7 +1362,7 @@ const planCaching = (connectionPlan, caching, platformProvider) => {
|
|
|
1353
1362
|
return {
|
|
1354
1363
|
kind: "cache",
|
|
1355
1364
|
provider,
|
|
1356
|
-
|
|
1365
|
+
clientSdkKeyDigest
|
|
1357
1366
|
};
|
|
1358
1367
|
};
|
|
1359
1368
|
const contextTagFor = (context, instanceId) => {
|
|
@@ -1389,15 +1398,30 @@ const isConfigStateMap = (candidate) => {
|
|
|
1389
1398
|
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return false;
|
|
1390
1399
|
return Object.values(candidate).every((config) => config && typeof config === "object" && typeof config.id === "string" && typeof config.key === "string");
|
|
1391
1400
|
};
|
|
1392
|
-
const isEntryFor = (
|
|
1401
|
+
const isEntryFor = (clientSdkKeyDigest, candidate) => {
|
|
1393
1402
|
if (!candidate || typeof candidate !== "object") return false;
|
|
1394
1403
|
const entry = candidate;
|
|
1395
|
-
return entry.formatVersion === ENTRY_FORMAT_VERSION && entry.
|
|
1404
|
+
return entry.formatVersion === ENTRY_FORMAT_VERSION && entry.clientSdkKeyDigest === clientSdkKeyDigest && isContextTag(entry.contextTag) && typeof entry.environmentId === "string" && typeof entry.projectId === "string" && isConfigStateMap(entry.configs) && typeof entry.receivedAt === "number";
|
|
1405
|
+
};
|
|
1406
|
+
const hasFirstFormatVersion = (candidate) => !!candidate && typeof candidate === "object" && candidate.formatVersion === FIRST_ENTRY_FORMAT_VERSION;
|
|
1407
|
+
const parseEntry = (raw, clientSdkKeyDigest) => {
|
|
1408
|
+
let candidate;
|
|
1409
|
+
try {
|
|
1410
|
+
candidate = JSON.parse(raw);
|
|
1411
|
+
} catch {
|
|
1412
|
+
return { outcome: "unreadable" };
|
|
1413
|
+
}
|
|
1414
|
+
if (isEntryFor(clientSdkKeyDigest, candidate)) return {
|
|
1415
|
+
outcome: "stored",
|
|
1416
|
+
cachedValues: candidate
|
|
1417
|
+
};
|
|
1418
|
+
if (hasFirstFormatVersion(candidate)) return { outcome: "first format" };
|
|
1419
|
+
return { outcome: "unreadable" };
|
|
1396
1420
|
};
|
|
1397
1421
|
var CachedValuesStore = class {
|
|
1398
|
-
constructor(provider,
|
|
1422
|
+
constructor(provider, clientSdkKeyDigest, logger) {
|
|
1399
1423
|
this.provider = provider;
|
|
1400
|
-
this.
|
|
1424
|
+
this.clientSdkKeyDigest = clientSdkKeyDigest;
|
|
1401
1425
|
this.logger = logger;
|
|
1402
1426
|
_defineProperty(this, "warned", /* @__PURE__ */ new Set());
|
|
1403
1427
|
_defineProperty(this, "pendingRead", void 0);
|
|
@@ -1422,23 +1446,16 @@ var CachedValuesStore = class {
|
|
|
1422
1446
|
return { outcome: "failed" };
|
|
1423
1447
|
}
|
|
1424
1448
|
if (raw == null || raw === "") return { outcome: "nothing stored" };
|
|
1425
|
-
const
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
}
|
|
1436
|
-
parseEntry(raw) {
|
|
1437
|
-
try {
|
|
1438
|
-
const candidate = JSON.parse(raw);
|
|
1439
|
-
return isEntryFor(this.clientSdkKey, candidate) ? candidate : void 0;
|
|
1440
|
-
} catch {
|
|
1441
|
-
return;
|
|
1449
|
+
const entryParseOutcome = parseEntry(raw, await this.clientSdkKeyDigest);
|
|
1450
|
+
switch (entryParseOutcome.outcome) {
|
|
1451
|
+
case "stored": return entryParseOutcome;
|
|
1452
|
+
case "first format":
|
|
1453
|
+
await this.removeEntry();
|
|
1454
|
+
return entryParseOutcome;
|
|
1455
|
+
case "unreadable":
|
|
1456
|
+
this.warnOnce("unreadable", "The values kept on the device could not be read and were removed, starting without them");
|
|
1457
|
+
await this.removeEntry();
|
|
1458
|
+
return entryParseOutcome;
|
|
1442
1459
|
}
|
|
1443
1460
|
}
|
|
1444
1461
|
async writeQueued() {
|
|
@@ -1457,7 +1474,7 @@ var CachedValuesStore = class {
|
|
|
1457
1474
|
async writeEntry(cachedValues) {
|
|
1458
1475
|
const entry = {
|
|
1459
1476
|
formatVersion: ENTRY_FORMAT_VERSION,
|
|
1460
|
-
|
|
1477
|
+
clientSdkKeyDigest: await this.clientSdkKeyDigest,
|
|
1461
1478
|
...cachedValues
|
|
1462
1479
|
};
|
|
1463
1480
|
const serialized = JSON.stringify(entry);
|
|
@@ -1522,7 +1539,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1522
1539
|
this.timeout = (_clientOptions$connec = clientOptions === null || clientOptions === void 0 || (_clientOptions$connec2 = clientOptions.connection) === null || _clientOptions$connec2 === void 0 ? void 0 : _clientOptions$connec2.timeout) !== null && _clientOptions$connec !== void 0 ? _clientOptions$connec : 3e3;
|
|
1523
1540
|
const urlFactory = (_internalClientOption = internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.urlFactory) !== null && _internalClientOption !== void 0 ? _internalClientOption : defaultUrlFactory;
|
|
1524
1541
|
this.connectionPlan = planConnection(clientSdkKey, clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.connection, urlFactory);
|
|
1525
|
-
this.cachedValuesStore = this.buildCachedValuesStore(planCaching(this.connectionPlan, clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.caching, internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.platformCachingProvider));
|
|
1542
|
+
this.cachedValuesStore = this.buildCachedValuesStore(planCaching(this.connectionPlan, clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.caching, internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.sha256HexDigest, internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.platformCachingProvider));
|
|
1526
1543
|
this.telemetryClient = this.buildTelemetryClient(liveTelemetryClient, clientOptions);
|
|
1527
1544
|
this.transport = (_internalClientOption2 = internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.transport) !== null && _internalClientOption2 !== void 0 ? _internalClientOption2 : this.buildTransport(sdkOptions, clientOptions, urlFactory, internalClientOptions);
|
|
1528
1545
|
this.transport.on("configSetReceived", (configSet) => {
|
|
@@ -1566,7 +1583,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1566
1583
|
this.logger.debug(`[ConfigDirectorClient] No values are kept on the device: ${cachingPlan.reason}`);
|
|
1567
1584
|
return;
|
|
1568
1585
|
case "cache": {
|
|
1569
|
-
const store = new CachedValuesStore(cachingPlan.provider, cachingPlan.
|
|
1586
|
+
const store = new CachedValuesStore(cachingPlan.provider, cachingPlan.clientSdkKeyDigest, this.logger);
|
|
1570
1587
|
store.read();
|
|
1571
1588
|
return store;
|
|
1572
1589
|
}
|
|
@@ -1582,6 +1599,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1582
1599
|
const read = await store.read();
|
|
1583
1600
|
switch (read.outcome) {
|
|
1584
1601
|
case "nothing stored":
|
|
1602
|
+
case "first format":
|
|
1585
1603
|
case "unreadable":
|
|
1586
1604
|
case "failed": return;
|
|
1587
1605
|
case "stored": break;
|
|
@@ -1779,7 +1797,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1779
1797
|
var _this$configSet, _this$handlersMap$get;
|
|
1780
1798
|
const configState = (_this$configSet = this.configSet) === null || _this$configSet === void 0 ? void 0 : _this$configSet.configs[configKey];
|
|
1781
1799
|
(_this$handlersMap$get = this.handlersMap.get(configKey)) === null || _this$handlersMap$get === void 0 || _this$handlersMap$get.forEach((h) => {
|
|
1782
|
-
const value = this.
|
|
1800
|
+
const value = this.evaluationOf(configKey, configState, h.defaultValue).value;
|
|
1783
1801
|
h.handler(value);
|
|
1784
1802
|
});
|
|
1785
1803
|
}
|
|
@@ -1804,12 +1822,15 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1804
1822
|
} else handlers.splice(0);
|
|
1805
1823
|
}
|
|
1806
1824
|
getValue(configKey, defaultValue) {
|
|
1825
|
+
return this.evaluate(configKey, defaultValue).value;
|
|
1826
|
+
}
|
|
1827
|
+
evaluate(configKey, defaultValue) {
|
|
1807
1828
|
var _this$configSet2;
|
|
1808
1829
|
this.validateDefaultValue(defaultValue);
|
|
1809
1830
|
const configState = (_this$configSet2 = this.configSet) === null || _this$configSet2 === void 0 ? void 0 : _this$configSet2.configs[configKey];
|
|
1810
|
-
return this.
|
|
1831
|
+
return this.evaluationOf(configKey, configState, defaultValue);
|
|
1811
1832
|
}
|
|
1812
|
-
|
|
1833
|
+
evaluationOf(configKey, configState, defaultValue) {
|
|
1813
1834
|
var _this$currentContext2, _parseResult$parsedVa;
|
|
1814
1835
|
if (!configState) {
|
|
1815
1836
|
var _this$currentContext;
|
|
@@ -1824,14 +1845,15 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1824
1845
|
usedDefault: true,
|
|
1825
1846
|
evaluationReason: reason
|
|
1826
1847
|
});
|
|
1827
|
-
|
|
1848
|
+
const evaluation = {
|
|
1828
1849
|
key: configKey,
|
|
1829
1850
|
value: defaultValue,
|
|
1830
1851
|
isDefaultValue: true,
|
|
1831
1852
|
reason,
|
|
1832
1853
|
context: this.context
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1854
|
+
};
|
|
1855
|
+
this.dispatchEvaluationEvent(evaluation);
|
|
1856
|
+
return evaluation;
|
|
1835
1857
|
}
|
|
1836
1858
|
const parseResult = parseConfigValue(configState, defaultValue);
|
|
1837
1859
|
const reason = this.servedReason(parseResult.reason);
|
|
@@ -1846,16 +1868,17 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1846
1868
|
usedDefault: parseResult.usedDefault,
|
|
1847
1869
|
evaluationReason: reason
|
|
1848
1870
|
});
|
|
1849
|
-
|
|
1871
|
+
const evaluation = {
|
|
1850
1872
|
key: configKey,
|
|
1851
1873
|
value: parseResult.parsedValue,
|
|
1852
1874
|
valueId: (_parseResult$parsedVa = parseResult.parsedValueId) !== null && _parseResult$parsedVa !== void 0 ? _parseResult$parsedVa : void 0,
|
|
1853
1875
|
isDefaultValue: parseResult.usedDefault,
|
|
1854
1876
|
reason,
|
|
1855
1877
|
context: this.context
|
|
1856
|
-
}
|
|
1878
|
+
};
|
|
1879
|
+
this.dispatchEvaluationEvent(evaluation);
|
|
1857
1880
|
this.logger.debug(`[ConfigDirectorClient] Evaluated '${configKey}' to '${parseResult.parsedValue}'`);
|
|
1858
|
-
return
|
|
1881
|
+
return evaluation;
|
|
1859
1882
|
}
|
|
1860
1883
|
dispatchEvaluationEvent(event) {
|
|
1861
1884
|
setTimeout(() => this.emit("configEvaluated", { evaluation: event }), 0);
|
|
@@ -23,13 +23,24 @@ interface ConfigDirectorLogger {
|
|
|
23
23
|
interface ConfigDirectorLogMessageDecorator {
|
|
24
24
|
decorateMessage(message: string): string;
|
|
25
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Why an evaluation returned the value it did. `found-match` returns a value from ConfigDirector,
|
|
28
|
+
* and `cached` a value kept on the device while a client SDK waits for live values. `value-missing`
|
|
29
|
+
* returns the in-code default value because the config has no value. Every other reason returns the
|
|
30
|
+
* in-code default value because of an error: the config does not exist (`config-state-missing`), no
|
|
31
|
+
* values have arrived yet (`client-not-ready`), or the value cannot be read as the type of the in-code
|
|
32
|
+
* default value.
|
|
33
|
+
*/
|
|
26
34
|
type EvaluationReason = "found-match" | "config-state-missing" | "client-not-ready" | "type-mismatch" | "value-missing" | "invalid-number" | "invalid-json" | "invalid-boolean" | "cached";
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
/**
|
|
36
|
+
* One evaluation of a config: the value it returned, why, and the context it was evaluated for.
|
|
37
|
+
*/
|
|
38
|
+
type ConfigEvaluation<T extends ConfigValueType = ConfigValueType> = {
|
|
39
|
+
/** The config key that was evaluated. */key: string; /** The value returned, which is the in-code default value when {@link isDefaultValue} is `true`. */
|
|
40
|
+
value: T; /** The ID ConfigDirector assigned to the value returned, when ConfigDirector sent one with it. */
|
|
41
|
+
valueId?: string; /** Whether the evaluation returned the in-code default value. */
|
|
42
|
+
isDefaultValue: boolean; /** Why the evaluation returned this value. */
|
|
43
|
+
reason: EvaluationReason; /** The context the config was evaluated for, if any. */
|
|
33
44
|
context?: ConfigDirectorContext;
|
|
34
45
|
};
|
|
35
46
|
/**
|
|
@@ -350,6 +361,16 @@ interface ConfigDirectorClient extends EventProvider<ClientEvents> {
|
|
|
350
361
|
* is called before initialization is done.
|
|
351
362
|
*/
|
|
352
363
|
getValue<T extends ConfigValueType>(configKey: string, defaultValue: T): T;
|
|
364
|
+
/**
|
|
365
|
+
* Evaluates a config as {@link getValue} does and returns the evaluation: the value, the reason it
|
|
366
|
+
* was served and its value ID. Like every read, it fires `configEvaluated` and is counted in
|
|
367
|
+
* telemetry.
|
|
368
|
+
*
|
|
369
|
+
* @returns The evaluation, whose `value` is what {@link getValue} returns
|
|
370
|
+
* @param configKey The config key to evaluate
|
|
371
|
+
* @param defaultValue The in-code default value, returned when no value from ConfigDirector can be served
|
|
372
|
+
*/
|
|
373
|
+
evaluate<T extends ConfigValueType>(configKey: string, defaultValue: T): ConfigEvaluation<T>;
|
|
353
374
|
/**
|
|
354
375
|
* Watches for changes to a a config evaluation value. Whenever the config value changes, the
|
|
355
376
|
* provided callback function will be called with the new value. Changes can happen due to updates
|
|
@@ -397,4 +418,4 @@ interface ConfigDirectorClient extends EventProvider<ClientEvents> {
|
|
|
397
418
|
dispose(): void;
|
|
398
419
|
}
|
|
399
420
|
//#endregion
|
|
400
|
-
export { ConfigDirectorClientOptions as a, NativeJsonValue as c, ConfigDirectorContext as d, ConfigDirectorLogMessageDecorator as f,
|
|
421
|
+
export { ConnectionMode as _, ConfigDirectorClientOptions as a, NativeJsonValue as c, ConfigDirectorContext as d, ConfigDirectorLogMessageDecorator as f, ConfigValueType as g, ConfigEvaluation as h, ConfigDirectorClient as i, NativeValue as l, ConfigDirectorLoggingLevel as m, CachingProvider as n, OfflineValue as o, ConfigDirectorLogger as p, ClientHooks as r, OfflineValues as s, CachingOptions as t, NativeValues as u, EvaluationReason as v };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configdirector/react-native-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "React Native client SDK for ConfigDirector. ConfigDirector is a remote configuration and feature flag service.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ConfigDirector",
|