@configdirector/react-native-sdk 1.9.1 → 1.10.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/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-CM98r0qu.mjs} +71 -43
- 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-CM98r0qu.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.1"
|
|
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-CM98r0qu.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.1"
|
|
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
|
|
@@ -1210,8 +1213,8 @@ var PollingTransport = class extends AbstractPollingTransport {
|
|
|
1210
1213
|
this.pollingIntervalSeconds = (_options$pollingInter = options.pollingInterval) !== null && _options$pollingInter !== void 0 ? _options$pollingInter : 60;
|
|
1211
1214
|
}
|
|
1212
1215
|
async connect(context, timeout) {
|
|
1213
|
-
|
|
1214
|
-
this.
|
|
1216
|
+
this.endCurrentConnection();
|
|
1217
|
+
const generation = this.connectionGeneration;
|
|
1215
1218
|
const clientSession = await this.options.clientSession;
|
|
1216
1219
|
if (generation !== this.connectionGeneration) return this;
|
|
1217
1220
|
try {
|
|
@@ -1226,9 +1229,14 @@ var PollingTransport = class extends AbstractPollingTransport {
|
|
|
1226
1229
|
return this;
|
|
1227
1230
|
}
|
|
1228
1231
|
close() {
|
|
1229
|
-
this.
|
|
1232
|
+
this.endCurrentConnection();
|
|
1230
1233
|
super.close();
|
|
1231
1234
|
}
|
|
1235
|
+
endCurrentConnection() {
|
|
1236
|
+
this.connectionGeneration++;
|
|
1237
|
+
this.clearPollingInterval();
|
|
1238
|
+
this.lastUpdateTimestamp = void 0;
|
|
1239
|
+
}
|
|
1232
1240
|
async fetchConfigs(context, timeout, clientSession) {
|
|
1233
1241
|
if (this.fatalError) {
|
|
1234
1242
|
this.logger.warn("[PollingTransport] There was a prior unrecoverable error. Ignoring attempt to reconnect.");
|
|
@@ -1331,11 +1339,12 @@ const utf8ByteLength = (text) => {
|
|
|
1331
1339
|
};
|
|
1332
1340
|
//#endregion
|
|
1333
1341
|
//#region ../js-client-core/src/cached-values.ts
|
|
1334
|
-
const ENTRY_FORMAT_VERSION =
|
|
1342
|
+
const ENTRY_FORMAT_VERSION = 2;
|
|
1343
|
+
const FIRST_ENTRY_FORMAT_VERSION = 1;
|
|
1335
1344
|
const DEFAULT_CONTEXT_KIND = "user";
|
|
1336
1345
|
const CACHED_VALUES_STORAGE_KEY_PREFIX = "configdirector-sdk:cached-values:";
|
|
1337
1346
|
const DEFAULT_CACHING_SIZE_LIMIT_BYTES = 256 * 1024;
|
|
1338
|
-
const planCaching = (connectionPlan, caching,
|
|
1347
|
+
const planCaching = (connectionPlan, caching, sha256HexDigest, platformCachingProvider) => {
|
|
1339
1348
|
var _caching$provider;
|
|
1340
1349
|
if (connectionPlan.kind === "stay-offline") return {
|
|
1341
1350
|
kind: "no cache",
|
|
@@ -1345,7 +1354,12 @@ const planCaching = (connectionPlan, caching, platformProvider) => {
|
|
|
1345
1354
|
kind: "no cache",
|
|
1346
1355
|
reason: "turned off"
|
|
1347
1356
|
};
|
|
1348
|
-
|
|
1357
|
+
if (!sha256HexDigest) return {
|
|
1358
|
+
kind: "no cache",
|
|
1359
|
+
reason: "no SHA-256 available"
|
|
1360
|
+
};
|
|
1361
|
+
const clientSdkKeyDigest = sha256HexDigest(connectionPlan.clientSdkKey);
|
|
1362
|
+
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
1363
|
if (!provider) return {
|
|
1350
1364
|
kind: "no cache",
|
|
1351
1365
|
reason: "no provider available"
|
|
@@ -1353,7 +1367,7 @@ const planCaching = (connectionPlan, caching, platformProvider) => {
|
|
|
1353
1367
|
return {
|
|
1354
1368
|
kind: "cache",
|
|
1355
1369
|
provider,
|
|
1356
|
-
|
|
1370
|
+
clientSdkKeyDigest
|
|
1357
1371
|
};
|
|
1358
1372
|
};
|
|
1359
1373
|
const contextTagFor = (context, instanceId) => {
|
|
@@ -1389,15 +1403,30 @@ const isConfigStateMap = (candidate) => {
|
|
|
1389
1403
|
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return false;
|
|
1390
1404
|
return Object.values(candidate).every((config) => config && typeof config === "object" && typeof config.id === "string" && typeof config.key === "string");
|
|
1391
1405
|
};
|
|
1392
|
-
const isEntryFor = (
|
|
1406
|
+
const isEntryFor = (clientSdkKeyDigest, candidate) => {
|
|
1393
1407
|
if (!candidate || typeof candidate !== "object") return false;
|
|
1394
1408
|
const entry = candidate;
|
|
1395
|
-
return entry.formatVersion === ENTRY_FORMAT_VERSION && entry.
|
|
1409
|
+
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";
|
|
1410
|
+
};
|
|
1411
|
+
const hasFirstFormatVersion = (candidate) => !!candidate && typeof candidate === "object" && candidate.formatVersion === FIRST_ENTRY_FORMAT_VERSION;
|
|
1412
|
+
const parseEntry = (raw, clientSdkKeyDigest) => {
|
|
1413
|
+
let candidate;
|
|
1414
|
+
try {
|
|
1415
|
+
candidate = JSON.parse(raw);
|
|
1416
|
+
} catch {
|
|
1417
|
+
return { outcome: "unreadable" };
|
|
1418
|
+
}
|
|
1419
|
+
if (isEntryFor(clientSdkKeyDigest, candidate)) return {
|
|
1420
|
+
outcome: "stored",
|
|
1421
|
+
cachedValues: candidate
|
|
1422
|
+
};
|
|
1423
|
+
if (hasFirstFormatVersion(candidate)) return { outcome: "first format" };
|
|
1424
|
+
return { outcome: "unreadable" };
|
|
1396
1425
|
};
|
|
1397
1426
|
var CachedValuesStore = class {
|
|
1398
|
-
constructor(provider,
|
|
1427
|
+
constructor(provider, clientSdkKeyDigest, logger) {
|
|
1399
1428
|
this.provider = provider;
|
|
1400
|
-
this.
|
|
1429
|
+
this.clientSdkKeyDigest = clientSdkKeyDigest;
|
|
1401
1430
|
this.logger = logger;
|
|
1402
1431
|
_defineProperty(this, "warned", /* @__PURE__ */ new Set());
|
|
1403
1432
|
_defineProperty(this, "pendingRead", void 0);
|
|
@@ -1422,23 +1451,16 @@ var CachedValuesStore = class {
|
|
|
1422
1451
|
return { outcome: "failed" };
|
|
1423
1452
|
}
|
|
1424
1453
|
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;
|
|
1454
|
+
const entryParseOutcome = parseEntry(raw, await this.clientSdkKeyDigest);
|
|
1455
|
+
switch (entryParseOutcome.outcome) {
|
|
1456
|
+
case "stored": return entryParseOutcome;
|
|
1457
|
+
case "first format":
|
|
1458
|
+
await this.removeEntry();
|
|
1459
|
+
return entryParseOutcome;
|
|
1460
|
+
case "unreadable":
|
|
1461
|
+
this.warnOnce("unreadable", "The values kept on the device could not be read and were removed, starting without them");
|
|
1462
|
+
await this.removeEntry();
|
|
1463
|
+
return entryParseOutcome;
|
|
1442
1464
|
}
|
|
1443
1465
|
}
|
|
1444
1466
|
async writeQueued() {
|
|
@@ -1457,7 +1479,7 @@ var CachedValuesStore = class {
|
|
|
1457
1479
|
async writeEntry(cachedValues) {
|
|
1458
1480
|
const entry = {
|
|
1459
1481
|
formatVersion: ENTRY_FORMAT_VERSION,
|
|
1460
|
-
|
|
1482
|
+
clientSdkKeyDigest: await this.clientSdkKeyDigest,
|
|
1461
1483
|
...cachedValues
|
|
1462
1484
|
};
|
|
1463
1485
|
const serialized = JSON.stringify(entry);
|
|
@@ -1522,7 +1544,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1522
1544
|
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
1545
|
const urlFactory = (_internalClientOption = internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.urlFactory) !== null && _internalClientOption !== void 0 ? _internalClientOption : defaultUrlFactory;
|
|
1524
1546
|
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));
|
|
1547
|
+
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
1548
|
this.telemetryClient = this.buildTelemetryClient(liveTelemetryClient, clientOptions);
|
|
1527
1549
|
this.transport = (_internalClientOption2 = internalClientOptions === null || internalClientOptions === void 0 ? void 0 : internalClientOptions.transport) !== null && _internalClientOption2 !== void 0 ? _internalClientOption2 : this.buildTransport(sdkOptions, clientOptions, urlFactory, internalClientOptions);
|
|
1528
1550
|
this.transport.on("configSetReceived", (configSet) => {
|
|
@@ -1566,7 +1588,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1566
1588
|
this.logger.debug(`[ConfigDirectorClient] No values are kept on the device: ${cachingPlan.reason}`);
|
|
1567
1589
|
return;
|
|
1568
1590
|
case "cache": {
|
|
1569
|
-
const store = new CachedValuesStore(cachingPlan.provider, cachingPlan.
|
|
1591
|
+
const store = new CachedValuesStore(cachingPlan.provider, cachingPlan.clientSdkKeyDigest, this.logger);
|
|
1570
1592
|
store.read();
|
|
1571
1593
|
return store;
|
|
1572
1594
|
}
|
|
@@ -1582,6 +1604,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1582
1604
|
const read = await store.read();
|
|
1583
1605
|
switch (read.outcome) {
|
|
1584
1606
|
case "nothing stored":
|
|
1607
|
+
case "first format":
|
|
1585
1608
|
case "unreadable":
|
|
1586
1609
|
case "failed": return;
|
|
1587
1610
|
case "stored": break;
|
|
@@ -1779,7 +1802,7 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1779
1802
|
var _this$configSet, _this$handlersMap$get;
|
|
1780
1803
|
const configState = (_this$configSet = this.configSet) === null || _this$configSet === void 0 ? void 0 : _this$configSet.configs[configKey];
|
|
1781
1804
|
(_this$handlersMap$get = this.handlersMap.get(configKey)) === null || _this$handlersMap$get === void 0 || _this$handlersMap$get.forEach((h) => {
|
|
1782
|
-
const value = this.
|
|
1805
|
+
const value = this.evaluationOf(configKey, configState, h.defaultValue).value;
|
|
1783
1806
|
h.handler(value);
|
|
1784
1807
|
});
|
|
1785
1808
|
}
|
|
@@ -1804,12 +1827,15 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1804
1827
|
} else handlers.splice(0);
|
|
1805
1828
|
}
|
|
1806
1829
|
getValue(configKey, defaultValue) {
|
|
1830
|
+
return this.evaluate(configKey, defaultValue).value;
|
|
1831
|
+
}
|
|
1832
|
+
evaluate(configKey, defaultValue) {
|
|
1807
1833
|
var _this$configSet2;
|
|
1808
1834
|
this.validateDefaultValue(defaultValue);
|
|
1809
1835
|
const configState = (_this$configSet2 = this.configSet) === null || _this$configSet2 === void 0 ? void 0 : _this$configSet2.configs[configKey];
|
|
1810
|
-
return this.
|
|
1836
|
+
return this.evaluationOf(configKey, configState, defaultValue);
|
|
1811
1837
|
}
|
|
1812
|
-
|
|
1838
|
+
evaluationOf(configKey, configState, defaultValue) {
|
|
1813
1839
|
var _this$currentContext2, _parseResult$parsedVa;
|
|
1814
1840
|
if (!configState) {
|
|
1815
1841
|
var _this$currentContext;
|
|
@@ -1824,14 +1850,15 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1824
1850
|
usedDefault: true,
|
|
1825
1851
|
evaluationReason: reason
|
|
1826
1852
|
});
|
|
1827
|
-
|
|
1853
|
+
const evaluation = {
|
|
1828
1854
|
key: configKey,
|
|
1829
1855
|
value: defaultValue,
|
|
1830
1856
|
isDefaultValue: true,
|
|
1831
1857
|
reason,
|
|
1832
1858
|
context: this.context
|
|
1833
|
-
}
|
|
1834
|
-
|
|
1859
|
+
};
|
|
1860
|
+
this.dispatchEvaluationEvent(evaluation);
|
|
1861
|
+
return evaluation;
|
|
1835
1862
|
}
|
|
1836
1863
|
const parseResult = parseConfigValue(configState, defaultValue);
|
|
1837
1864
|
const reason = this.servedReason(parseResult.reason);
|
|
@@ -1846,16 +1873,17 @@ var DefaultConfigDirectorClient = class DefaultConfigDirectorClient {
|
|
|
1846
1873
|
usedDefault: parseResult.usedDefault,
|
|
1847
1874
|
evaluationReason: reason
|
|
1848
1875
|
});
|
|
1849
|
-
|
|
1876
|
+
const evaluation = {
|
|
1850
1877
|
key: configKey,
|
|
1851
1878
|
value: parseResult.parsedValue,
|
|
1852
1879
|
valueId: (_parseResult$parsedVa = parseResult.parsedValueId) !== null && _parseResult$parsedVa !== void 0 ? _parseResult$parsedVa : void 0,
|
|
1853
1880
|
isDefaultValue: parseResult.usedDefault,
|
|
1854
1881
|
reason,
|
|
1855
1882
|
context: this.context
|
|
1856
|
-
}
|
|
1883
|
+
};
|
|
1884
|
+
this.dispatchEvaluationEvent(evaluation);
|
|
1857
1885
|
this.logger.debug(`[ConfigDirectorClient] Evaluated '${configKey}' to '${parseResult.parsedValue}'`);
|
|
1858
|
-
return
|
|
1886
|
+
return evaluation;
|
|
1859
1887
|
}
|
|
1860
1888
|
dispatchEvaluationEvent(event) {
|
|
1861
1889
|
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.1",
|
|
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",
|