@configdirector/react-native-sdk 1.7.0 → 1.9.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 CHANGED
@@ -10,9 +10,11 @@ React Native SDK for [ConfigDirector](https://www.configdirector.com), remote co
10
10
  npm install --save @configdirector/react-native-sdk
11
11
  ```
12
12
 
13
- Install `@react-native-async-storage/async-storage` as well, so the SDK can keep the same client
14
- session for six hours across app starts. It is an optional peer dependency and works in Expo Go.
15
- Without it, every app start begins a new client session and the SDK logs a warning.
13
+ Install `@react-native-async-storage/async-storage` as well, so the SDK recognizes the app install
14
+ across app starts. For a context without an `id`, ConfigDirector derives an identifier from an ID
15
+ the SDK stores for the install, so the context keeps that identifier, and counts as one monthly
16
+ active user, however often the app is opened. It is an optional peer dependency and works in Expo
17
+ Go. Without it, every app start looks like a new install and the SDK logs a warning.
16
18
 
17
19
  ```bash
18
20
  npm install --save @react-native-async-storage/async-storage
@@ -86,7 +88,7 @@ transform, so a Jest setup must let `transformIgnorePatterns` transform both pac
86
88
  `jest-expo` requires `@react-native/jest-preset` as a peer dependency, so install it in either case.
87
89
  The test client never touches AsyncStorage. A test that builds a real client instead, through
88
90
  `createClient` or a provider given an `sdkKey`, logs the warning that AsyncStorage is missing and
89
- starts a new client session under either preset; add `@babel/plugin-transform-dynamic-import` to the
91
+ connects as a new install under either preset; add `@babel/plugin-transform-dynamic-import` to the
90
92
  Babel test environment for that client to use the AsyncStorage Jest mock instead.
91
93
 
92
94
  ## Documentation
@@ -1,4 +1,4 @@
1
- import { i as ConfigDirectorContext, n as ConfigDirectorClient, o as ConfigDirectorLogger } from "./types-P1hoU2Ru.mjs";
1
+ import { c as NativeJsonValue, d as ConfigDirectorContext, i as ConfigDirectorClient, l as NativeValue, p as ConfigDirectorLogger, u as NativeValues } from "./types-BBQmjjf5.mjs";
2
2
 
3
3
  //#region ../shared/src/errors.d.ts
4
4
  declare class ConfigDirectorConnectionError extends Error {
@@ -11,15 +11,6 @@ declare class ConfigDirectorValidationError extends Error {
11
11
  constructor(message: string);
12
12
  }
13
13
  //#endregion
14
- //#region ../shared/src/testing/values.d.ts
15
- type TestJsonValue = boolean | number | string | null | TestJsonValue[] | {
16
- [key: string]: TestJsonValue;
17
- };
18
- type TestValue = boolean | number | string | TestJsonValue[] | {
19
- [key: string]: TestJsonValue;
20
- };
21
- type TestValues = Record<string, TestValue>;
22
- //#endregion
23
14
  //#region ../js-client-core/src/testing/TestClient.d.ts
24
15
  /**
25
16
  * Options for {@link createTestClient}. Every option is optional.
@@ -30,7 +21,7 @@ type TestClientOptions = {
30
21
  * config type follows from each value: a boolean, an integral number (`integer`), any other
31
22
  * number (`float`), a string, or a plain object or array (`json`).
32
23
  */
33
- values?: TestValues;
24
+ values?: NativeValues;
34
25
  /**
35
26
  * The connection timeout of the SDK client, in milliseconds. It bounds how long a held
36
27
  * `initialize` or `updateContext` waits. Defaults to the SDK's production timeout.
@@ -59,7 +50,7 @@ interface TestClient {
59
50
  * Stores `value` under `key` and, when the client is connected, delivers it as an update, so
60
51
  * reads, watchers, and `configsUpdated` handlers see it.
61
52
  */
62
- setValue(key: string, value: TestValue): void;
53
+ setValue(key: string, value: NativeValue): void;
63
54
  /**
64
55
  * Removes `key` and, when the client is connected, delivers a full update without it, so reads
65
56
  * fall back to the in-code default value and watchers of `key` receive that default.
@@ -69,7 +60,7 @@ interface TestClient {
69
60
  * Replaces every stored value with `values`, disarms any armed hold or failure, and, when the
70
61
  * client is connected, delivers the new values as a full update.
71
62
  */
72
- replaceValues(values: TestValues): void;
63
+ replaceValues(values: NativeValues): void;
73
64
  /**
74
65
  * Makes the next `initialize` wait until {@link completeInitialization} or
75
66
  * {@link failInitialization} is called, or until the client's timeout elapses.
@@ -155,4 +146,4 @@ declare const installTestClient: (testClient: TestClient) => (() => void);
155
146
  */
156
147
  declare const createTestClient: (options?: TestClientOptions) => TestClient;
157
148
  //#endregion
158
- export { ConfigDirectorConnectionError, ConfigDirectorValidationError, type TestClient, type TestClientOptions, type TestJsonValue, type TestValue, type TestValues, createTestClient, installTestClient };
149
+ export { ConfigDirectorConnectionError, ConfigDirectorValidationError, type TestClient, type TestClientOptions, type NativeJsonValue as TestJsonValue, type NativeValue as TestValue, type NativeValues as TestValues, createTestClient, installTestClient };
@@ -1,98 +1,4 @@
1
- import { c as ConfigDirectorConnectionError, d as _defineProperty, l as ConfigDirectorValidationError, o as createDefaultLogger, r as DefaultConfigDirectorClient, t as INSTALLED_TEST_CLIENT_SLOT, u as Emitter } from "./installedTestClient-LWv5ji8J.mjs";
2
- //#region ../shared/src/testing/values.ts
3
- const encodeTestValue$1 = (key, value) => {
4
- if (key.trim().length == 0) throw new ConfigDirectorValidationError("Invalid config key. The key of a test value cannot be empty.");
5
- return encode(key, value);
6
- };
7
- const encode = (key, value) => {
8
- switch (typeof value) {
9
- case "boolean": return {
10
- type: "boolean",
11
- value: value ? "true" : "false"
12
- };
13
- case "number": return encodeNumber(key, value);
14
- case "string": return {
15
- type: "string",
16
- value
17
- };
18
- case "object": if (value !== null) {
19
- assertJsonContents(key, value, "");
20
- return {
21
- type: "json",
22
- value: JSON.stringify(value)
23
- };
24
- }
25
- }
26
- throw new ConfigDirectorValidationError(`Invalid test value for '${key}': ${describe(value)}. Use a boolean, a number, a string, a plain object, or an array.`);
27
- };
28
- const encodeNumber = (key, value) => {
29
- if (!Number.isFinite(value)) throw new ConfigDirectorValidationError(`Invalid test value for '${key}': ${describe(value)} is not a finite number.`);
30
- if (Number.isInteger(value)) {
31
- if (!Number.isSafeInteger(value)) throw new ConfigDirectorValidationError(`Invalid test value for '${key}': ${value} is not a safe integer, so the SDK could not read it back exactly.`);
32
- return {
33
- type: "integer",
34
- value: String(value)
35
- };
36
- }
37
- return {
38
- type: "float",
39
- value: toPlainDecimal(value)
40
- };
41
- };
42
- const toPlainDecimal = (value) => {
43
- const text = String(value);
44
- const exponentIndex = text.indexOf("e-");
45
- if (exponentIndex < 0) return text;
46
- const sign = text.startsWith("-") ? "-" : "";
47
- const [integerDigits = "", fractionDigits = ""] = text.slice(sign.length, exponentIndex).split(".");
48
- const leadingZeros = Number(text.slice(exponentIndex + 2)) - integerDigits.length;
49
- return `${sign}0.${"0".repeat(leadingZeros)}${integerDigits}${fractionDigits}`;
50
- };
51
- const assertJsonContents = (key, value, path) => {
52
- if (value === null || typeof value === "boolean" || typeof value === "string") return;
53
- if (typeof value === "number") {
54
- if (!Number.isFinite(value)) throw invalidJsonContents(key, path, `${describe(value)} is not a finite number`);
55
- return;
56
- }
57
- if (Array.isArray(value)) {
58
- value.forEach((item, index) => assertJsonContents(key, item, `${path}[${index}]`));
59
- return;
60
- }
61
- if (isPlainObject(value)) {
62
- for (const [property, item] of Object.entries(value)) assertJsonContents(key, item, path ? `${path}.${property}` : property);
63
- return;
64
- }
65
- throw invalidJsonContents(key, path, `${describe(value)} cannot be encoded as JSON`);
66
- };
67
- const invalidJsonContents = (key, path, problem) => new ConfigDirectorValidationError(`Invalid test value for '${key}'${path ? ` at '${path}'` : ""}: ${problem}. JSON contents can hold booleans, finite numbers, strings, null, arrays, and plain objects.`);
68
- const isPlainObject = (value) => {
69
- if (typeof value !== "object" || value === null) return false;
70
- const prototype = Object.getPrototypeOf(value);
71
- return prototype === Object.prototype || prototype === null;
72
- };
73
- const describe = (value) => {
74
- if (value === null) return "null";
75
- if (typeof value === "function") return "a function";
76
- if (typeof value === "object") {
77
- var _value$constructor$na, _value$constructor;
78
- return `a ${(_value$constructor$na = (_value$constructor = value.constructor) === null || _value$constructor === void 0 ? void 0 : _value$constructor.name) !== null && _value$constructor$na !== void 0 ? _value$constructor$na : "object"} instance`;
79
- }
80
- if (typeof value === "symbol") return "a symbol";
81
- return String(value);
82
- };
83
- //#endregion
84
- //#region ../js-client-core/src/testing/values.ts
85
- const encodeTestValue = (key, value, revision) => {
86
- const encoded = encodeTestValue$1(key, value);
87
- return {
88
- id: `test-config:${key}`,
89
- key,
90
- type: encoded.type,
91
- value: encoded.value,
92
- valueId: `test-value:${key}:${revision}`
93
- };
94
- };
95
- //#endregion
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-BluKT8Qj.mjs";
96
2
  //#region ../js-client-core/src/testing/InMemoryConnection.ts
97
3
  const TEST_ENVIRONMENT = {
98
4
  environmentId: "test-environment",
@@ -129,7 +35,7 @@ var InMemoryConnection = class {
129
35
  return [...this.recordedContexts];
130
36
  }
131
37
  setValue(key, value) {
132
- const configState = encodeTestValue(key, value, ++this.revision);
38
+ const configState = this.encode(key, value);
133
39
  this.configs.set(key, configState);
134
40
  this.deliverIfConnected({
135
41
  ...TEST_ENVIRONMENT,
@@ -278,19 +184,16 @@ var InMemoryConnection = class {
278
184
  }
279
185
  encodeAll(values) {
280
186
  const encoded = /* @__PURE__ */ new Map();
281
- for (const [key, value] of Object.entries(values)) encoded.set(key, encodeTestValue(key, value, ++this.revision));
187
+ for (const [key, value] of Object.entries(values)) encoded.set(key, this.encode(key, value));
282
188
  return encoded;
283
189
  }
190
+ encode(key, value) {
191
+ return nativeValueConfigState(`test-config:${key}`, key, value, `test-value:${key}:${++this.revision}`);
192
+ }
284
193
  };
285
194
  //#endregion
286
195
  //#region ../js-client-core/src/testing/TestClient.ts
287
196
  const TEST_CLIENT_SDK_KEY = "test-client";
288
- const noopTelemetryClient = {
289
- updateContext: async () => {},
290
- evaluatedConfig: () => {},
291
- recordInvalidContext: () => {},
292
- close: async () => {}
293
- };
294
197
  var InMemoryTestClient = class {
295
198
  constructor(client, connection) {
296
199
  this.client = client;
@@ -331,7 +234,7 @@ const createTestClient$1 = (sdkOptions, options) => {
331
234
  var _options$logger, _options$values;
332
235
  const logger = (_options$logger = options === null || options === void 0 ? void 0 : options.logger) !== null && _options$logger !== void 0 ? _options$logger : createDefaultLogger();
333
236
  const connection = new InMemoryConnection(logger, (_options$values = options === null || options === void 0 ? void 0 : options.values) !== null && _options$values !== void 0 ? _options$values : {});
334
- return new InMemoryTestClient(new DefaultConfigDirectorClient(noopTelemetryClient, TEST_CLIENT_SDK_KEY, sdkOptions, {
237
+ return new InMemoryTestClient(new DefaultConfigDirectorClient(() => discardingTelemetryClient, TEST_CLIENT_SDK_KEY, sdkOptions, {
335
238
  logger,
336
239
  connection: { timeout: options === null || options === void 0 ? void 0 : options.timeout }
337
240
  }, { transport: connection }), connection);
@@ -392,7 +295,7 @@ const installTestClient = (testClient) => {
392
295
  const createTestClient = (options) => {
393
296
  return createTestClient$1({
394
297
  sdkName: "react-native-sdk",
395
- sdkVersion: "1.7.0"
298
+ sdkVersion: "1.9.0"
396
299
  }, options);
397
300
  };
398
301
  //#endregion
@@ -1,4 +1,4 @@
1
- import { a as ConfigDirectorLogMessageDecorator, c as ConfigValueType, i as ConfigDirectorContext, l as ConnectionMode, n as ConfigDirectorClient, o as ConfigDirectorLogger, r as ConfigDirectorClientOptions, s as ConfigDirectorLoggingLevel, t as ClientHooks } from "./types-P1hoU2Ru.mjs";
1
+ import { a as ConfigDirectorClientOptions, d as ConfigDirectorContext, f as ConfigDirectorLogMessageDecorator, g as ConnectionMode, h as ConfigValueType, i as ConfigDirectorClient, m as ConfigDirectorLoggingLevel, n as CachingProvider, o as OfflineValue, p as ConfigDirectorLogger, r as ClientHooks, s as OfflineValues, t as CachingOptions } from "./types-BBQmjjf5.mjs";
2
2
  import { Component, PropsWithChildren } from "react";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
@@ -39,19 +39,31 @@ type NetInfoState = {
39
39
  */
40
40
  type NetInfoSubscribe = (callback: (state: NetInfoState) => void) => () => void;
41
41
  type ConfigDirectorProviderOptions = {
42
- sdkKey: string;
42
+ /**
43
+ * Your ConfigDirector client SDK key. Required unless `mode` is `offline`.
44
+ */
45
+ sdkKey?: string;
43
46
  appName?: string;
44
47
  appVersion?: string;
45
48
  url?: string;
46
49
  timeout?: number;
47
50
  /**
48
- * The connection mode, one of `streaming` or `polling`. In `streaming` mode the connection stays
49
- * open and receives config updates as they happen. In `polling` mode configs are fetched once during
50
- * initialization and then again on every `pollingInterval`.
51
+ * The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
52
+ * stays open and receives config updates as they happen. In `polling` mode configs are fetched once
53
+ * during initialization and then again on every `pollingInterval`. In `offline` mode the client never
54
+ * connects to ConfigDirector and sends nothing: it serves `values` to every context, or the in-code
55
+ * default values when none are given, and needs no `sdkKey`.
51
56
  *
52
57
  * Defaults to `streaming`.
53
58
  */
54
59
  mode?: ConnectionMode;
60
+ /**
61
+ * The values to serve in `offline` mode, keyed by config key. The config type of each value follows
62
+ * from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
63
+ * a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
64
+ * to initialize.
65
+ */
66
+ values?: OfflineValues;
55
67
  /**
56
68
  * The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
57
69
  *
@@ -62,6 +74,12 @@ type ConfigDirectorProviderOptions = {
62
74
  context?: ConfigDirectorContext;
63
75
  logger?: ConfigDirectorLogger;
64
76
  hooks?: ClientHooks;
77
+ /**
78
+ * Options for the values the client keeps on the device between launches. The last values received
79
+ * are kept by default and served, with the evaluation reason `cached`, on the next launch of the same
80
+ * context until live values arrive.
81
+ */
82
+ caching?: CachingOptions;
65
83
  netInfoSubscribe?: NetInfoSubscribe;
66
84
  };
67
85
  /**
@@ -133,4 +151,4 @@ declare class ConfigDirectorReactContextError extends Error {
133
151
  //#region src/logger.d.ts
134
152
  declare const createConsoleLogger: (level?: ConfigDirectorLoggingLevel) => DefaultConsoleLogger;
135
153
  //#endregion
136
- export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientOptions, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorProvider, type ConfigDirectorProviderClientProps, type ConfigDirectorProviderOptions, type ConfigDirectorProviderProps, ConfigDirectorReactContextError, type ConnectionMode, type NetInfoSubscribe, 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 ConnectionMode, type NetInfoSubscribe, type OfflineValue, type OfflineValues, createClient, createConsoleLogger, useClient, useConfigValue, useContext };
@@ -1,7 +1,8 @@
1
- import { a as CLIENT_BASE_URL, d as _defineProperty, i as fetchWithTimeout, n as readInstalledTestClient, o as createDefaultLogger, r as DefaultConfigDirectorClient, s as isFetchErrorFatal } from "./installedTestClient-LWv5ji8J.mjs";
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-BluKT8Qj.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";
5
+ import { bytesToHex } from "@noble/hashes/utils.js";
5
6
  import { jsx } from "react/jsx-runtime";
6
7
  //#region ../shared/src/telemetry/utils.ts
7
8
  const CONFIG_VALUE_MAX_LENGTH = 500;
@@ -520,8 +521,8 @@ const resolveMetadata = (provided, logger) => {
520
521
  return metadata;
521
522
  };
522
523
  //#endregion
523
- //#region src/instanceIdStorage.ts
524
- const lookUpAsyncStorage = async () => {
524
+ //#region src/asyncStorage.ts
525
+ const importAsyncStorage = async () => {
525
526
  try {
526
527
  const { default: storage } = await import("@react-native-async-storage/async-storage");
527
528
  return {
@@ -532,23 +533,10 @@ const lookUpAsyncStorage = async () => {
532
533
  return { outcome: "not installed" };
533
534
  }
534
535
  };
535
- const asyncStorageInstanceIdStorage = (logger) => {
536
- const asyncStorageLookup = lookUpAsyncStorage().then((lookup) => {
537
- if (lookup.outcome === "not installed") logger.warn("The ConfigDirector SDK could not find @react-native-async-storage/async-storage, so every app start counts as a new client session. Install it for the SDK to keep the client session for six hours across app starts.");
538
- return lookup;
539
- });
540
- const installedAsyncStorage = async () => {
541
- const lookup = await asyncStorageLookup;
542
- switch (lookup.outcome) {
543
- case "installed": return lookup.storage;
544
- case "not installed": throw new Error("@react-native-async-storage/async-storage is not installed");
545
- }
546
- };
547
- return {
548
- getItem: async (key) => (await installedAsyncStorage()).getItem(key),
549
- setItem: async (key, value) => (await installedAsyncStorage()).setItem(key, value)
550
- };
551
- };
536
+ const findAsyncStorage = (logger) => importAsyncStorage().then((lookup) => {
537
+ if (lookup.outcome === "not installed") logger.warn("The ConfigDirector SDK could not find @react-native-async-storage/async-storage, so every app start looks like a new install to ConfigDirector, a context without an id gets a new identifier each time, and no values are kept on the device between app starts. Install it for the SDK to recognize the install across app starts and to serve the last values when the app starts without a network.");
538
+ return lookup;
539
+ });
552
540
  //#endregion
553
541
  //#region src/utf8Encoder.ts
554
542
  /**
@@ -590,6 +578,42 @@ const encodeManually = (str) => {
590
578
  return new Uint8Array(bytes);
591
579
  };
592
580
  //#endregion
581
+ //#region src/cachingProvider.ts
582
+ const storageKeyFor = (clientSdkKey) => CACHED_VALUES_STORAGE_KEY_PREFIX + bytesToHex(sha256(encodeUtf8(clientSdkKey)));
583
+ const asyncStorageCachingProvider = (asyncStorage) => (clientSdkKey) => {
584
+ const storageKey = storageKeyFor(clientSdkKey);
585
+ return {
586
+ read: async () => {
587
+ const lookup = await asyncStorage;
588
+ return lookup.outcome === "installed" ? lookup.storage.getItem(storageKey) : void 0;
589
+ },
590
+ write: async (value) => {
591
+ const lookup = await asyncStorage;
592
+ if (lookup.outcome === "installed") await lookup.storage.setItem(storageKey, value);
593
+ },
594
+ remove: async () => {
595
+ const lookup = await asyncStorage;
596
+ if (lookup.outcome === "installed") await lookup.storage.removeItem(storageKey);
597
+ },
598
+ sizeLimit: () => DEFAULT_CACHING_SIZE_LIMIT_BYTES
599
+ };
600
+ };
601
+ //#endregion
602
+ //#region src/instanceIdStorage.ts
603
+ const asyncStorageInstanceIdStorage = (asyncStorage) => {
604
+ const installedAsyncStorage = async () => {
605
+ const lookup = await asyncStorage;
606
+ switch (lookup.outcome) {
607
+ case "installed": return lookup.storage;
608
+ case "not installed": throw new Error("@react-native-async-storage/async-storage is not installed");
609
+ }
610
+ };
611
+ return {
612
+ getItem: async (key) => (await installedAsyncStorage()).getItem(key),
613
+ setItem: async (key, value) => (await installedAsyncStorage()).setItem(key, value)
614
+ };
615
+ };
616
+ //#endregion
593
617
  //#region src/reactNativeStreamingFetch.ts
594
618
  const abortError = (message) => {
595
619
  const err = new Error(message);
@@ -742,19 +766,21 @@ var MinimalUrl = class {
742
766
  const urlFactory = (input, base) => new MinimalUrl(input, base);
743
767
  //#endregion
744
768
  //#region src/client.ts
745
- const createClient = (clientSdkKey, clientOptions) => {
746
- var _clientOptions$logger, _clientOptions$connec;
769
+ const createClient = (clientSdkKey, clientOptions) => createReactNativeClient(clientSdkKey, clientOptions);
770
+ const createReactNativeClient = (clientSdkKey, clientOptions) => {
771
+ var _clientOptions$logger;
747
772
  const sdkIdentity = {
748
773
  sdkName: "react-native-sdk",
749
- sdkVersion: "1.7.0"
774
+ sdkVersion: "1.9.0"
750
775
  };
751
776
  const logger = (_clientOptions$logger = clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.logger) !== null && _clientOptions$logger !== void 0 ? _clientOptions$logger : createConsoleLogger("warn");
752
777
  const metadata = resolveMetadata(clientOptions === null || clientOptions === void 0 ? void 0 : clientOptions.metadata, logger);
753
- return new DefaultConfigDirectorClient(new ReactNativeTelemetryClient({
754
- sdkKey: clientSdkKey,
778
+ const asyncStorage = findAsyncStorage(logger);
779
+ return new DefaultConfigDirectorClient((liveTelemetry) => new ReactNativeTelemetryClient({
780
+ sdkKey: liveTelemetry.clientSdkKey,
755
781
  sdkIdentity,
756
782
  metaContext: metadata,
757
- baseUrl: (clientOptions === null || clientOptions === void 0 || (_clientOptions$connec = clientOptions.connection) === null || _clientOptions$connec === void 0 ? void 0 : _clientOptions$connec.url) ? urlFactory(clientOptions.connection.url) : CLIENT_BASE_URL,
783
+ baseUrl: liveTelemetry.baseUrl,
758
784
  logger,
759
785
  urlFactory
760
786
  }), clientSdkKey, sdkIdentity, {
@@ -764,26 +790,29 @@ const createClient = (clientSdkKey, clientOptions) => {
764
790
  }, {
765
791
  fetch: reactNativeStreamingFetch,
766
792
  urlFactory,
767
- instanceIdStorage: asyncStorageInstanceIdStorage(logger)
793
+ instanceIdStorage: asyncStorageInstanceIdStorage(asyncStorage),
794
+ platformCachingProvider: asyncStorageCachingProvider(asyncStorage)
768
795
  });
769
796
  };
770
797
  //#endregion
771
798
  //#region src/clientSource.ts
772
799
  const buildClient = (options) => {
773
800
  var _options$logger;
774
- return createClient(options.sdkKey, {
801
+ return createReactNativeClient(options.sdkKey, {
775
802
  connection: {
776
803
  url: options.url,
777
804
  timeout: options.timeout,
778
805
  mode: options.mode,
779
- pollingInterval: options.pollingInterval
806
+ pollingInterval: options.pollingInterval,
807
+ values: options.values
780
808
  },
781
809
  metadata: {
782
810
  appName: options.appName,
783
811
  appVersion: options.appVersion
784
812
  },
785
813
  logger: (_options$logger = options.logger) !== null && _options$logger !== void 0 ? _options$logger : createConsoleLogger("warn"),
786
- hooks: options.hooks
814
+ hooks: options.hooks,
815
+ caching: options.caching
787
816
  });
788
817
  };
789
818
  const hasGivenClient = (props) => "client" in props && props.client !== void 0;
@@ -804,6 +833,7 @@ const resolveClientSource = (props) => {
804
833
  };
805
834
  //#endregion
806
835
  //#region src/provider.tsx
836
+ const settledStatusOf = (client) => (client === null || client === void 0 ? void 0 : client.isReady) ? "ready" : "default";
807
837
  var ConfigDirectorProvider = class extends Component {
808
838
  constructor(props) {
809
839
  super(props);
@@ -871,15 +901,15 @@ var ConfigDirectorProvider = class extends Component {
871
901
  break;
872
902
  case "none": return;
873
903
  }
874
- if (!client.isReady) this.setState({ status: "default" });
904
+ this.setState({ status: settledStatusOf(client) });
875
905
  }
876
906
  async componentDidUpdate(prevProps) {
877
907
  if (hasGivenClient(prevProps) && hasGivenClient(this.props) && prevProps.client !== this.props.client) createConsoleLogger("warn").warn("The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.");
878
908
  if (!deepEqual(prevProps.context, this.props.context)) {
879
- var _this$state$client3, _this$props$context, _this$state$client4;
909
+ var _this$state$client3, _this$props$context;
880
910
  this.setState({ status: "loading" });
881
911
  await ((_this$state$client3 = this.state.client) === null || _this$state$client3 === void 0 ? void 0 : _this$state$client3.updateContext((_this$props$context = this.props.context) !== null && _this$props$context !== void 0 ? _this$props$context : {}));
882
- if (!((_this$state$client4 = this.state.client) === null || _this$state$client4 === void 0 ? void 0 : _this$state$client4.isReady)) this.setState({ status: "default" });
912
+ this.setState({ status: settledStatusOf(this.state.client) });
883
913
  }
884
914
  }
885
915
  componentWillUnmount() {
@@ -891,8 +921,8 @@ var ConfigDirectorProvider = class extends Component {
891
921
  (_this$handlers = this.handlers) === null || _this$handlers === void 0 || _this$handlers.removeAll();
892
922
  this.handlers = void 0;
893
923
  if (this.ownsClient) {
894
- var _this$state$client5;
895
- (_this$state$client5 = this.state.client) === null || _this$state$client5 === void 0 || _this$state$client5.dispose();
924
+ var _this$state$client4;
925
+ (_this$state$client4 = this.state.client) === null || _this$state$client4 === void 0 || _this$state$client4.dispose();
896
926
  this.disposedOwnClient = true;
897
927
  }
898
928
  }