@splitsoftware/splitio-commons 3.0.0-rc.3 → 3.0.0-rc.5

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.
Files changed (75) hide show
  1. package/CHANGES.txt +1 -1
  2. package/cjs/listeners/browser.js +2 -2
  3. package/cjs/logger/messages/debug.js +1 -1
  4. package/cjs/presets/serverSide.js +2 -2
  5. package/cjs/sdkClient/sdkLifecycle.js +2 -2
  6. package/cjs/sdkFactory/index.js +4 -4
  7. package/cjs/services/authProvider.js +2 -2
  8. package/cjs/services/decorateHeaders.js +2 -1
  9. package/cjs/services/secureSplitHttpClient.js +1 -1
  10. package/cjs/services/serviceApi.js +145 -0
  11. package/cjs/services/splitApi.js +13 -14
  12. package/cjs/services/splitHttpClient.js +3 -5
  13. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +1 -1
  14. package/cjs/sync/polling/pollingManagerCS.js +2 -2
  15. package/cjs/sync/polling/updaters/definitionChangesUpdater.js +8 -8
  16. package/cjs/sync/streaming/AuthClient/index.js +1 -1
  17. package/cjs/sync/streaming/pushManager.js +2 -2
  18. package/cjs/sync/submitters/eventsSubmitter.js +1 -1
  19. package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
  20. package/cjs/sync/submitters/impressionsSubmitter.js +1 -1
  21. package/cjs/sync/submitters/telemetrySubmitter.js +3 -3
  22. package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
  23. package/cjs/sync/syncManagerOnline.js +1 -1
  24. package/cjs/utils/settingsValidation/index.js +1 -1
  25. package/esm/listeners/browser.js +2 -2
  26. package/esm/logger/messages/debug.js +1 -1
  27. package/esm/presets/serverSide.js +2 -2
  28. package/esm/sdkClient/sdkLifecycle.js +2 -2
  29. package/esm/sdkFactory/index.js +4 -4
  30. package/esm/services/authProvider.js +2 -2
  31. package/esm/services/decorateHeaders.js +2 -1
  32. package/esm/services/secureSplitHttpClient.js +1 -1
  33. package/esm/services/serviceApi.js +141 -0
  34. package/esm/services/splitApi.js +13 -14
  35. package/esm/services/splitHttpClient.js +3 -5
  36. package/esm/sync/polling/fetchers/splitChangesFetcher.js +1 -1
  37. package/esm/sync/polling/pollingManagerCS.js +2 -2
  38. package/esm/sync/polling/updaters/definitionChangesUpdater.js +8 -8
  39. package/esm/sync/streaming/AuthClient/index.js +1 -1
  40. package/esm/sync/streaming/pushManager.js +2 -2
  41. package/esm/sync/submitters/eventsSubmitter.js +1 -1
  42. package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
  43. package/esm/sync/submitters/impressionsSubmitter.js +1 -1
  44. package/esm/sync/submitters/telemetrySubmitter.js +3 -3
  45. package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
  46. package/esm/sync/syncManagerOnline.js +1 -1
  47. package/esm/utils/settingsValidation/index.js +1 -1
  48. package/package.json +1 -1
  49. package/src/listeners/browser.ts +4 -4
  50. package/src/logger/messages/debug.ts +1 -1
  51. package/src/presets/serverSide.ts +2 -2
  52. package/src/sdkClient/sdkLifecycle.ts +2 -2
  53. package/src/sdkFactory/index.ts +4 -4
  54. package/src/sdkFactory/types.ts +7 -7
  55. package/src/services/authProvider.ts +2 -2
  56. package/src/services/decorateHeaders.ts +2 -1
  57. package/src/services/secureSplitHttpClient.ts +1 -1
  58. package/src/services/serviceApi.ts +166 -0
  59. package/src/services/splitApi.ts +19 -18
  60. package/src/services/splitHttpClient.ts +7 -4
  61. package/src/services/types.ts +2 -2
  62. package/src/storages/types.ts +3 -3
  63. package/src/sync/polling/fetchers/splitChangesFetcher.ts +1 -1
  64. package/src/sync/polling/pollingManagerCS.ts +2 -2
  65. package/src/sync/polling/updaters/definitionChangesUpdater.ts +9 -9
  66. package/src/sync/streaming/AuthClient/index.ts +1 -1
  67. package/src/sync/streaming/pushManager.ts +2 -2
  68. package/src/sync/submitters/eventsSubmitter.ts +1 -1
  69. package/src/sync/submitters/impressionCountsSubmitter.ts +1 -1
  70. package/src/sync/submitters/impressionsSubmitter.ts +1 -1
  71. package/src/sync/submitters/telemetrySubmitter.ts +3 -3
  72. package/src/sync/submitters/uniqueKeysSubmitter.ts +1 -1
  73. package/src/sync/syncManagerOnline.ts +1 -1
  74. package/src/utils/settingsValidation/index.ts +1 -1
  75. package/types/splitio.d.ts +8 -8
@@ -13,7 +13,7 @@ import { FallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCal
13
13
  * Modular SDK factory
14
14
  */
15
15
  export function sdkFactory(params) {
16
- var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
16
+ var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, serviceApiFactory = params.serviceApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
17
17
  var log = settings.log, initialRolloutPlan = settings.initialRolloutPlan, key = settings.core.key;
18
18
  // @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
19
19
  // On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
@@ -45,9 +45,9 @@ export function sdkFactory(params) {
45
45
  var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
46
46
  var impressionsTracker = impressionsTrackerFactory(params, storage, integrationsManager);
47
47
  var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
48
- // splitApi is used by SyncManager and Browser signal listener
49
- var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
50
- var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackCalculator: fallbackCalculator };
48
+ // serviceApi is used by SyncManager and Browser signal listener
49
+ var serviceApi = serviceApiFactory && serviceApiFactory(settings, platform, telemetryTracker);
50
+ var ctx = { clients: clients, serviceApi: serviceApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackCalculator: fallbackCalculator };
51
51
  ctx.syncManager = syncManagerFactory && syncManagerFactory(ctx);
52
52
  // SDK client and manager
53
53
  var clientMethod = sdkClientMethodFactory(ctx);
@@ -13,8 +13,8 @@ function isExpired(credential) {
13
13
  export function authProviderFactory(settings, splitHttpClient, telemetryTracker) {
14
14
  var urls = settings.urls, log = settings.log;
15
15
  function fetchAuth() {
16
- var url = "".concat(urls.auth, "/v3/auth?capabilities=config");
17
- return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
16
+ var url = "".concat(urls.auth, "/api/v3/auth?capabilities=config");
17
+ return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN), false, true);
18
18
  }
19
19
  var authenticate = authenticateFactory(fetchAuth);
20
20
  var backoff = new Backoff(fetchCredential);
@@ -12,7 +12,8 @@ var FORBIDDEN_HEADERS = new Set([
12
12
  'content-encoding',
13
13
  'accept',
14
14
  'keep-alive',
15
- 'x-fastly-debug'
15
+ 'x-fastly-debug',
16
+ 'x-harness-fme-sdk-version'
16
17
  ]);
17
18
  export function decorateHeaders(settings, headers) {
18
19
  var _a;
@@ -13,7 +13,7 @@ export function secureSplitHttpClientFactory(settings, platform, telemetryTracke
13
13
  var splitHttpClient = splitHttpClientFactory(settings, platform);
14
14
  var authProvider = authProviderFactory(settings, splitHttpClient, telemetryTracker);
15
15
  function makeRequest(url, options, latencyTracker, logErrorsAsInfo, token) {
16
- return splitHttpClient(url, __assign(__assign({}, options), { headers: __assign(__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo);
16
+ return splitHttpClient(url, __assign(__assign({}, options), { headers: __assign(__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo, true);
17
17
  }
18
18
  var httpClient = function (url, options, latencyTracker, logErrorsAsInfo) {
19
19
  return authProvider.credential().then(function (credential) {
@@ -0,0 +1,141 @@
1
+ import { splitHttpClientFactory } from './splitHttpClient';
2
+ import { objectAssign } from '../utils/lang/objectAssign';
3
+ import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MEMBERSHIPS } from '../utils/constants';
4
+ import { ERROR_TOO_MANY_SETS } from '../logger/constants';
5
+ var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
6
+ function userKeyToQueryParam(userKey) {
7
+ return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
8
+ }
9
+ /**
10
+ * Factory of ServiceApi objects, which group the collection of HTTP endpoints used by the SDKs
11
+ *
12
+ * @param settings - validated settings object
13
+ * @param platform - object containing environment-specific dependencies
14
+ * @param telemetryTracker - telemetry tracker
15
+ * @param secureSplitHttpClientFactory - factory of SecureSplitHttpClient objects
16
+ */
17
+ export function serviceApiFactory(settings, platform, telemetryTracker, secureSplitHttpClientFactory) {
18
+ var urls = settings.urls;
19
+ var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
20
+ var SplitSDKImpressionsMode = settings.sync.impressionsMode;
21
+ var splitHttpClient = splitHttpClientFactory(settings, platform);
22
+ var secureSplitHttpClient = secureSplitHttpClientFactory(settings, platform, telemetryTracker);
23
+ return {
24
+ // @TODO throw errors if health check requests fail, to log them in the Synchronizer
25
+ getSdkAPIHealthCheck: function () {
26
+ var url = "".concat(urls.sdk, "/api/version");
27
+ return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
28
+ },
29
+ getEventsAPIHealthCheck: function () {
30
+ var url = "".concat(urls.events, "/api/version");
31
+ return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
32
+ },
33
+ fetchAuth: function (userMatchingKeys) {
34
+ var url = "".concat(urls.auth, "/api/v2/auth?s=").concat(settings.sync.flagSpecVersion);
35
+ if (userMatchingKeys) { // `userMatchingKeys` is undefined in server-side
36
+ var queryParams = userMatchingKeys.map(userKeyToQueryParam).join('&');
37
+ if (queryParams)
38
+ url += '&' + queryParams;
39
+ }
40
+ return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
41
+ },
42
+ fetchSplitChanges: function (since, noCache, till, rbSince) {
43
+ var url = "".concat(urls.sdk, "/api/splitChanges?s=").concat(settings.sync.flagSpecVersion, "&since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
44
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SPLITS))
45
+ .catch(function (err) {
46
+ if (err.statusCode === 414)
47
+ settings.log.error(ERROR_TOO_MANY_SETS);
48
+ throw err;
49
+ });
50
+ },
51
+ fetchSegmentChanges: function (since, segmentName, noCache, till) {
52
+ var url = "".concat(urls.sdk, "/api/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
53
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
54
+ },
55
+ // @TODO support filterQueryString and handle ERROR_TOO_MANY_SETS error
56
+ fetchConfigs: function (since, noCache, till) {
57
+ var url = "".concat(urls.configs, "/api/v1/configs?since=").concat(since).concat(filterQueryString || '').concat(till ? '&till=' + till : '');
58
+ return secureSplitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
59
+ },
60
+ fetchConfigsSegmentChanges: function (since, segmentName, noCache, till) {
61
+ var url = "".concat(urls.configs, "/api/v1/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
62
+ return secureSplitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
63
+ },
64
+ fetchMemberships: function (userMatchingKey, noCache, till) {
65
+ /**
66
+ * URI encoding of user keys in order to:
67
+ * - avoid 400 responses (due to URI malformed). E.g.: '/api/memberships/%'
68
+ * - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
69
+ * - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
70
+ */
71
+ var url = "".concat(urls.sdk, "/api/memberships/").concat(encodeURIComponent(userMatchingKey)).concat(till ? '?till=' + till : '');
72
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MEMBERSHIPS));
73
+ },
74
+ /**
75
+ * Post events.
76
+ *
77
+ * @param body - Events bulk payload
78
+ * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
79
+ */
80
+ postEventsBulk: function (body, headers) {
81
+ var url = "".concat(urls.events, "/api/events/bulk");
82
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(EVENTS));
83
+ },
84
+ /**
85
+ * Post impressions.
86
+ *
87
+ * @param body - Impressions bulk payload
88
+ * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
89
+ */
90
+ postTestImpressionsBulk: function (body, headers) {
91
+ var url = "".concat(urls.events, "/api/testImpressions/bulk");
92
+ return splitHttpClient(url, {
93
+ // Adding extra headers to send impressions in OPTIMIZED or DEBUG modes.
94
+ method: 'POST',
95
+ body: body,
96
+ headers: objectAssign({ SplitSDKImpressionsMode: SplitSDKImpressionsMode }, headers)
97
+ }, telemetryTracker.trackHttp(IMPRESSIONS));
98
+ },
99
+ /**
100
+ * Post impressions counts.
101
+ *
102
+ * @param body - Impressions counts payload
103
+ * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
104
+ */
105
+ postTestImpressionsCount: function (body, headers) {
106
+ var url = "".concat(urls.events, "/api/testImpressions/count");
107
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(IMPRESSIONS_COUNT));
108
+ },
109
+ /**
110
+ * Post unique keys for client side.
111
+ *
112
+ * @param body - unique keys payload
113
+ * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
114
+ */
115
+ postUniqueKeysBulkCs: function (body, headers) {
116
+ var url = "".concat(urls.telemetry, "/api/v1/keys/cs");
117
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
118
+ },
119
+ /**
120
+ * Post unique keys for server side.
121
+ *
122
+ * @param body - unique keys payload
123
+ * @param headers - Optionals headers to overwrite default ones. For example, it is used in producer mode to overwrite metadata headers.
124
+ */
125
+ postUniqueKeysBulkSs: function (body, headers) {
126
+ var url = "".concat(urls.telemetry, "/api/v1/keys/ss");
127
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY));
128
+ },
129
+ postMetricsConfig: function (body, headers) {
130
+ var url = "".concat(urls.telemetry, "/api/v1/metrics/config");
131
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
132
+ },
133
+ postMetricsUsage: function (body, headers) {
134
+ var url = "".concat(urls.telemetry, "/api/v1/metrics/usage");
135
+ return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
136
+ },
137
+ stop: function () {
138
+ secureSplitHttpClient.stop();
139
+ }
140
+ };
141
+ }
@@ -6,19 +6,19 @@ var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
6
6
  function userKeyToQueryParam(userKey) {
7
7
  return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
8
8
  }
9
+ // @TODO remove when migrating to the new `urls` defaults.
9
10
  /**
10
- * Factory of SplitApi objects, which group the collection of Split HTTP endpoints used by the SDK
11
+ * Factory of ServiceApi objects, which group the collection of Split HTTP endpoints used by the SDK
11
12
  *
12
13
  * @param settings - validated settings object
13
14
  * @param platform - object containing environment-specific dependencies
14
15
  * @param telemetryTracker - telemetry tracker
15
16
  */
16
- export function splitApiFactory(settings, platform, telemetryTracker, secureSplitHttpClientFactory) {
17
+ export function splitApiFactory(settings, platform, telemetryTracker) {
17
18
  var urls = settings.urls;
18
19
  var filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
19
20
  var SplitSDKImpressionsMode = settings.sync.impressionsMode;
20
21
  var splitHttpClient = splitHttpClientFactory(settings, platform);
21
- var secureSplitHttpClient = secureSplitHttpClientFactory ? secureSplitHttpClientFactory(settings, platform, telemetryTracker) : undefined;
22
22
  return {
23
23
  // @TODO throw errors if health check requests fail, to log them in the Synchronizer
24
24
  getSdkAPIHealthCheck: function () {
@@ -51,15 +51,6 @@ export function splitApiFactory(settings, platform, telemetryTracker, secureSpli
51
51
  var url = "".concat(urls.sdk, "/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
52
52
  return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
53
53
  },
54
- // @TODO support filterQueryString and handle ERROR_TOO_MANY_SETS error
55
- fetchConfigs: function (since, noCache, till) {
56
- var url = "".concat(urls.configs, "/v1/configs?since=").concat(since).concat(filterQueryString || '').concat(till ? '&till=' + till : '');
57
- return (secureSplitHttpClient || splitHttpClient)(url, noCache ? noCacheHeaderOptions : undefined);
58
- },
59
- fetchConfigsSegmentChanges: function (since, segmentName, noCache, till) {
60
- var url = "".concat(urls.configs, "/v1/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
61
- return (secureSplitHttpClient || splitHttpClient)(url, noCache ? noCacheHeaderOptions : undefined);
62
- },
63
54
  fetchMemberships: function (userMatchingKey, noCache, till) {
64
55
  /**
65
56
  * URI encoding of user keys in order to:
@@ -133,9 +124,17 @@ export function splitApiFactory(settings, platform, telemetryTracker, secureSpli
133
124
  var url = "".concat(urls.telemetry, "/v1/metrics/usage");
134
125
  return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(TELEMETRY), true);
135
126
  },
127
+ // Not used. Just here to satisfy the IServiceApi interface.
128
+ fetchConfigs: function (since, noCache, till) {
129
+ var url = "".concat(urls.configs, "/v1/configs?since=").concat(since).concat(filterQueryString || '').concat(till ? '&till=' + till : '');
130
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
131
+ },
132
+ fetchConfigsSegmentChanges: function (since, segmentName, noCache, till) {
133
+ var url = "".concat(urls.configs, "/v1/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
134
+ return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
135
+ },
136
136
  stop: function () {
137
- if (secureSplitHttpClient)
138
- secureSplitHttpClient.stop();
137
+ // no-op
139
138
  }
140
139
  };
141
140
  }
@@ -21,19 +21,17 @@ export function splitHttpClientFactory(settings, _a) {
21
21
  var commonHeaders = {
22
22
  'Accept': 'application/json',
23
23
  'Content-Type': 'application/json',
24
- 'Authorization': "Bearer ".concat(authorizationKey),
25
- 'SplitSDKVersion': version
24
+ 'Authorization': "Bearer ".concat(authorizationKey)
26
25
  };
27
26
  if (ip)
28
27
  commonHeaders['SplitSDKMachineIP'] = ip;
29
28
  if (hostname)
30
29
  commonHeaders['SplitSDKMachineName'] = removeNonISO88591(hostname);
31
- return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo) {
30
+ return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo, newVersionHeader) {
32
31
  if (reqOpts === void 0) { reqOpts = {}; }
33
32
  if (latencyTracker === void 0) { latencyTracker = function () { }; }
34
- if (logErrorsAsInfo === void 0) { logErrorsAsInfo = false; }
35
33
  var request = objectAssign({
36
- headers: decorateHeaders(settings, objectAssign({}, commonHeaders, reqOpts.headers || {})),
34
+ headers: decorateHeaders(settings, objectAssign(newVersionHeader ? { 'X-Harness-FME-SDK-Version': version } : { 'SplitSDKVersion': version }, commonHeaders, reqOpts.headers || {})),
37
35
  method: reqOpts.method || 'GET',
38
36
  body: reqOpts.body
39
37
  }, options);
@@ -21,7 +21,7 @@ function partitionByStatus(items, till, since) {
21
21
  */
22
22
  // @TODO breaking: drop support for Split Proxy below v5.10.0 and simplify the implementation
23
23
  export function splitChangesFetcherFactory(params) {
24
- var fetchSplitChanges = params.splitApi.fetchSplitChanges, settings = params.settings, storage = params.storage;
24
+ var fetchSplitChanges = params.serviceApi.fetchSplitChanges, settings = params.settings, storage = params.storage;
25
25
  var log = settings.log;
26
26
  var PROXY_CHECK_INTERVAL_MILLIS = checkIfServerSide(settings) ? PROXY_CHECK_INTERVAL_MILLIS_SS : PROXY_CHECK_INTERVAL_MILLIS_CS;
27
27
  var lastProxyCheckTimestamp;
@@ -10,7 +10,7 @@ import { usesSegmentsSync } from '../../storages/AbstractDefinitionsCacheSync';
10
10
  * For client-side API with multiple clients.
11
11
  */
12
12
  export function pollingManagerCSFactory(params, definitionChangesFetcher) {
13
- var splitApi = params.splitApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
13
+ var serviceApi = params.serviceApi, storage = params.storage, readiness = params.readiness, settings = params.settings;
14
14
  var log = settings.log;
15
15
  var definitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings, true);
16
16
  // Map of matching keys to their corresponding MySegmentsSyncTask.
@@ -44,7 +44,7 @@ export function pollingManagerCSFactory(params, definitionChangesFetcher) {
44
44
  }
45
45
  });
46
46
  function add(matchingKey, readiness, storage) {
47
- var mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
47
+ var mySegmentsSyncTask = mySegmentsSyncTaskFactory(serviceApi.fetchMemberships, storage, readiness, settings, matchingKey);
48
48
  // smart ready
49
49
  function smartReady(metadata) {
50
50
  if (!readiness.isReady() && !usesSegmentsSync(storage))
@@ -69,7 +69,7 @@ function matchFilters(definition, filters) {
69
69
  export function computeMutation(update, segments, filters) {
70
70
  return update.updated.reduce(function (accum, ruleEntity) {
71
71
  if (!filters || matchFilters(ruleEntity, filters)) {
72
- accum.added.push(ruleEntity);
72
+ accum.updated.push(ruleEntity);
73
73
  parseSegments(ruleEntity).forEach(function (segmentName) {
74
74
  segments.add(segmentName);
75
75
  });
@@ -79,7 +79,7 @@ export function computeMutation(update, segments, filters) {
79
79
  }
80
80
  accum.names.push(ruleEntity.name);
81
81
  return accum;
82
- }, { added: [], removed: update.removed, names: update.removed.slice() });
82
+ }, { updated: [], removed: update.removed, names: update.removed.slice() });
83
83
  }
84
84
  function convertInstantUpdateToDefinitionChanges(instantUpdate) {
85
85
  var payload = instantUpdate.payload, changeNumber = instantUpdate.changeNumber;
@@ -143,16 +143,16 @@ export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, s
143
143
  var updatedDefinitions = [];
144
144
  var ffUpdate = false;
145
145
  if (definitionChanges.d) {
146
- var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
146
+ var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), updated = _a.updated, removed = _a.removed, names = _a.names;
147
147
  updatedDefinitions = names;
148
- log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, added.length, removed.length]);
149
- ffUpdate = definitions.update(added, removed, definitionChanges.d.till);
148
+ log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, updated.length, removed.length]);
149
+ ffUpdate = definitions.update(updated, removed, definitionChanges.d.till);
150
150
  }
151
151
  var rbsUpdate = false;
152
152
  if (definitionChanges.rbs) {
153
- var _b = computeMutation(definitionChanges.rbs, usedSegments), added = _b.added, removed = _b.removed;
154
- log.debug(SYNC_UPDATE, ['rule-based segments', added.length, removed.length]);
155
- rbsUpdate = rbSegments.update(added, removed, definitionChanges.rbs.till);
153
+ var _b = computeMutation(definitionChanges.rbs, usedSegments), updated = _b.updated, removed = _b.removed;
154
+ log.debug(SYNC_UPDATE, ['rule-based segments', updated.length, removed.length]);
155
+ rbsUpdate = rbSegments.update(updated, removed, definitionChanges.rbs.till);
156
156
  }
157
157
  return Promise.all([ffUpdate, rbsUpdate,
158
158
  // @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
@@ -5,7 +5,7 @@ import { hash } from '../../../utils/murmur3/murmur3';
5
5
  /**
6
6
  * Factory of authentication function.
7
7
  *
8
- * @param fetchAuth - `SplitAPI.fetchAuth` endpoint
8
+ * @param fetchAuth - `ServiceApi.fetchAuth` endpoint
9
9
  */
10
10
  export function authenticateFactory(fetchAuth) {
11
11
  /**
@@ -20,7 +20,7 @@ import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
20
20
  * - for client-side, with support for multiple clients, if key is provided in settings
21
21
  */
22
22
  export function pushManagerFactory(params, pollingManager) {
23
- var settings = params.settings, storage = params.storage, splitApi = params.splitApi, readiness = params.readiness, platform = params.platform, telemetryTracker = params.telemetryTracker;
23
+ var settings = params.settings, storage = params.storage, serviceApi = params.serviceApi, readiness = params.readiness, platform = params.platform, telemetryTracker = params.telemetryTracker;
24
24
  // `userKey` is the matching key of main client in client-side SDK.
25
25
  // It can be used to check if running on client-side or server-side SDK.
26
26
  var userKey = checkIfServerSide(settings) ? undefined : getMatching(settings.core.key);
@@ -34,7 +34,7 @@ export function pushManagerFactory(params, pollingManager) {
34
34
  log.warn(STREAMING_FALLBACK, [e]);
35
35
  return;
36
36
  }
37
- var authenticate = authenticateFactory(splitApi.fetchAuth);
37
+ var authenticate = authenticateFactory(serviceApi.fetchAuth);
38
38
  // init feedback loop
39
39
  var pushEmitter = new platform.EventEmitter();
40
40
  var sseHandler = SSEHandlerFactory(log, pushEmitter, telemetryTracker);
@@ -4,7 +4,7 @@ import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
4
4
  * Submitter that periodically posts tracked events
5
5
  */
6
6
  export function eventsSubmitterFactory(params) {
7
- var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.splitApi.postEventsBulk, events = params.storage.events;
7
+ var _a = params.settings, log = _a.log, eventsPushRate = _a.scheduler.eventsPushRate, eventsFirstPushWindow = _a.startup.eventsFirstPushWindow, postEventsBulk = params.serviceApi.postEventsBulk, events = params.storage.events;
8
8
  // don't retry events.
9
9
  var submitter = submitterFactory(log, postEventsBulk, events, eventsPushRate);
10
10
  // Set a timer for the first push window of events.
@@ -25,7 +25,7 @@ var IMPRESSIONS_COUNT_RATE = 1800000; // 30 minutes
25
25
  * Submitter that periodically posts impression counts
26
26
  */
27
27
  export function impressionCountsSubmitterFactory(params) {
28
- var log = params.settings.log, postTestImpressionsCount = params.splitApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
28
+ var log = params.settings.log, postTestImpressionsCount = params.serviceApi.postTestImpressionsCount, impressionCounts = params.storage.impressionCounts;
29
29
  // retry impressions counts only once.
30
30
  return submitterFactory(log, postTestImpressionsCount, impressionCounts, IMPRESSIONS_COUNT_RATE, fromImpressionCountsCollector, 1);
31
31
  }
@@ -31,7 +31,7 @@ export function fromImpressionsCollector(sendLabels, entityType, data) {
31
31
  * Submitter that periodically posts impressions data
32
32
  */
33
33
  export function impressionsSubmitterFactory(params) {
34
- var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.splitApi.postTestImpressionsBulk, impressions = params.storage.impressions, entityType = params.entityType;
34
+ var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.serviceApi.postTestImpressionsBulk, impressions = params.storage.impressions, entityType = params.entityType;
35
35
  // retry impressions only once.
36
36
  var syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled, entityType), 1);
37
37
  // register impressions submitter to be executed when impressions cache is full
@@ -102,9 +102,9 @@ export function telemetrySubmitterFactory(params) {
102
102
  var telemetry = params.storage.telemetry, now = params.platform.now;
103
103
  if (!telemetry || !now)
104
104
  return; // No submitter created if telemetry cache is not defined
105
- var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness;
105
+ var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, serviceApi = params.serviceApi, readiness = params.readiness;
106
106
  var stopTimer = timer(now);
107
- var submitter = firstPushWindowDecorator(submitterFactory(log, splitApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
107
+ var submitter = firstPushWindowDecorator(submitterFactory(log, serviceApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
108
108
  readiness.gate.once(SDK_READY_FROM_CACHE, function () {
109
109
  telemetry.recordTimeUntilReadyFromCache(stopTimer());
110
110
  });
@@ -112,7 +112,7 @@ export function telemetrySubmitterFactory(params) {
112
112
  telemetry.recordTimeUntilReady(stopTimer());
113
113
  // Post config data when the SDK is ready and if the telemetry submitter was started
114
114
  if (submitter.isRunning()) {
115
- var postMetricsConfigTask = submitterFactory(log, splitApi.postMetricsConfig, telemetryCacheConfigAdapter(telemetry, settings), 0, undefined, 0, true);
115
+ var postMetricsConfigTask = submitterFactory(log, serviceApi.postMetricsConfig, telemetryCacheConfigAdapter(telemetry, settings), 0, undefined, 0, true);
116
116
  postMetricsConfigTask.execute();
117
117
  }
118
118
  });
@@ -5,7 +5,7 @@ var UNIQUE_KEYS_RATE = 900000; // 15 minutes
5
5
  * Submitter that periodically posts impression counts
6
6
  */
7
7
  export function uniqueKeysSubmitterFactory(params) {
8
- var _a = params.settings, log = _a.log, key = _a.core.key, _b = params.splitApi, postUniqueKeysBulkCs = _b.postUniqueKeysBulkCs, postUniqueKeysBulkSs = _b.postUniqueKeysBulkSs, uniqueKeys = params.storage.uniqueKeys;
8
+ var _a = params.settings, log = _a.log, key = _a.core.key, _b = params.serviceApi, postUniqueKeysBulkCs = _b.postUniqueKeysBulkCs, postUniqueKeysBulkSs = _b.postUniqueKeysBulkSs, uniqueKeys = params.storage.uniqueKeys;
9
9
  var isClientSide = key !== undefined;
10
10
  var postUniqueKeysBulk = isClientSide ? postUniqueKeysBulkCs : postUniqueKeysBulkSs;
11
11
  var syncTask = submitterFactory(log, postUniqueKeysBulk, uniqueKeys, UNIQUE_KEYS_RATE);
@@ -18,7 +18,7 @@ import { segmentChangesFetcherFactory } from './polling/fetchers/segmentChangesF
18
18
  */
19
19
  export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory, definitionFetcherFactory, segmentFetcherFactory) {
20
20
  if (definitionFetcherFactory === void 0) { definitionFetcherFactory = splitChangesFetcherFactory; }
21
- if (segmentFetcherFactory === void 0) { segmentFetcherFactory = function (params) { return segmentChangesFetcherFactory(params.splitApi.fetchSegmentChanges); }; }
21
+ if (segmentFetcherFactory === void 0) { segmentFetcherFactory = function (params) { return segmentChangesFetcherFactory(params.serviceApi.fetchSegmentChanges); }; }
22
22
  /**
23
23
  * SyncManager factory for modular SDK
24
24
  */
@@ -53,7 +53,7 @@ export var base = {
53
53
  // Telemetry Server
54
54
  telemetry: 'https://telemetry.split.io/api',
55
55
  // Configs Server
56
- configs: 'https://configs.split.io/api',
56
+ configs: 'https://configs.split.io',
57
57
  },
58
58
  // Defines which kind of storage we should instantiate.
59
59
  storage: undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "3.0.0-rc.3",
3
+ "version": "3.0.0-rc.5",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -3,7 +3,7 @@ import { ISignalListener } from './types';
3
3
  import { IRecorderCacheSync, IStorageSync } from '../storages/types';
4
4
  import { fromImpressionsCollector } from '../sync/submitters/impressionsSubmitter';
5
5
  import { fromImpressionCountsCollector } from '../sync/submitters/impressionCountsSubmitter';
6
- import { IResponse, ISplitApi } from '../services/types';
6
+ import { IResponse, IServiceApi } from '../services/types';
7
7
  import { ISettings } from '../types';
8
8
  import SplitIO from '../../types/splitio';
9
9
  import { ImpressionsPayload } from '../sync/submitters/types';
@@ -25,14 +25,14 @@ export class BrowserSignalListener implements ISignalListener {
25
25
  private syncManager: ISyncManager | undefined;
26
26
  private settings: ISettings;
27
27
  private storage: IStorageSync;
28
- private serviceApi: ISplitApi;
28
+ private serviceApi: IServiceApi;
29
29
  private fromImpressionsCollector: (data: SplitIO.ImpressionDTO[]) => ImpressionsPayload;
30
30
 
31
- constructor({ syncManager, settings, storage, splitApi, entityType }: ISdkFactoryContextSync) {
31
+ constructor({ syncManager, settings, storage, serviceApi, entityType }: ISdkFactoryContextSync) {
32
32
  this.syncManager = syncManager;
33
33
  this.settings = settings;
34
34
  this.storage = storage;
35
- this.serviceApi = splitApi;
35
+ this.serviceApi = serviceApi;
36
36
  this.flushData = this.flushData.bind(this);
37
37
  this.flushDataIfHidden = this.flushDataIfHidden.bind(this);
38
38
  this.fromImpressionsCollector = fromImpressionsCollector.bind(undefined, settings.core.labelsEnabled, entityType);
@@ -22,7 +22,7 @@ export const codesDebug: [number, string][] = codesInfo.concat([
22
22
  // synchronizer
23
23
  [c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
24
24
  [c.SYNC_FETCH, c.LOG_PREFIX_SYNC + 'Spin up %s updates using since = %s and rbSince = %s.'],
25
- [c.SYNC_UPDATE, c.LOG_PREFIX_SYNC + 'New %s: %s. Removed: %s.'],
25
+ [c.SYNC_UPDATE, c.LOG_PREFIX_SYNC + 'Updated %s: %s. Removed: %s.'],
26
26
  [c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
27
27
  [c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + 'Starting %s. Running each %s millis'],
28
28
  [c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + 'Running %s'],
@@ -1,4 +1,4 @@
1
- import { splitApiFactory } from '../services/splitApi';
1
+ import { serviceApiFactory } from '../services/serviceApi';
2
2
  import { syncManagerOnlineFactory } from '../sync/syncManagerOnline';
3
3
  import { pushManagerFactory } from '../sync/streaming/pushManager';
4
4
  import { pollingManagerSSFactory } from '../sync/polling/pollingManagerSS';
@@ -11,7 +11,7 @@ const syncManagerOnlineSSFactory = syncManagerOnlineFactory(pollingManagerSSFact
11
11
 
12
12
  export const serverSideModules = {
13
13
  storageFactory: InMemoryStorageFactory,
14
- splitApiFactory,
14
+ serviceApiFactory,
15
15
  syncManagerFactory: syncManagerOnlineSSFactory,
16
16
  sdkManagerFactory,
17
17
  sdkClientMethodFactory,
@@ -7,7 +7,7 @@ const COOLDOWN_TIME_IN_MILLIS = 1000;
7
7
  * Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
8
8
  */
9
9
  export function sdkLifecycleFactory(params: ISdkFactoryContext, isSharedClient?: boolean): { init(): void; flush(): Promise<void>; destroy(): Promise<void> } {
10
- const { sdkReadinessManager, syncManager, storage, settings, telemetryTracker, impressionsTracker, platform, splitApi } = params;
10
+ const { sdkReadinessManager, syncManager, storage, settings, telemetryTracker, impressionsTracker, platform, serviceApi } = params;
11
11
 
12
12
  let hasInit = false;
13
13
  let lastActionTime = 0;
@@ -68,7 +68,7 @@ export function sdkLifecycleFactory(params: ISdkFactoryContext, isSharedClient?:
68
68
 
69
69
  // Stop background jobs
70
70
  syncManager && syncManager.stop();
71
- splitApi && splitApi.stop();
71
+ serviceApi && serviceApi.stop();
72
72
 
73
73
  return __flush().then(() => {
74
74
  // Cleanup storage
@@ -18,7 +18,7 @@ import { FallbackTreatmentsCalculator } from '../evaluator/fallbackTreatmentsCal
18
18
  */
19
19
  export function sdkFactory(params: ISdkFactoryParams): SplitIO.ISDK | SplitIO.IAsyncSDK | SplitIO.IBrowserSDK | SplitIO.IBrowserAsyncSDK {
20
20
 
21
- const { settings, platform, storageFactory, splitApiFactory, extraProps, syncManagerFactory,
21
+ const { settings, platform, storageFactory, serviceApiFactory, extraProps, syncManagerFactory,
22
22
  integrationsManagerFactory, sdkManagerFactory, sdkClientMethodFactory, lazyInit } = params;
23
23
  const { log, initialRolloutPlan, core: { key } } = settings;
24
24
 
@@ -58,10 +58,10 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ISDK | SplitIO.IA
58
58
  const impressionsTracker = impressionsTrackerFactory(params, storage, integrationsManager);
59
59
  const eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager, storage.telemetry);
60
60
 
61
- // splitApi is used by SyncManager and Browser signal listener
62
- const splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
61
+ // serviceApi is used by SyncManager and Browser signal listener
62
+ const serviceApi = serviceApiFactory && serviceApiFactory(settings, platform, telemetryTracker);
63
63
 
64
- const ctx: ISdkFactoryContext = { clients, splitApi, eventTracker, impressionsTracker, telemetryTracker, sdkReadinessManager, readiness, settings, storage, platform, fallbackCalculator };
64
+ const ctx: ISdkFactoryContext = { clients, serviceApi, eventTracker, impressionsTracker, telemetryTracker, sdkReadinessManager, readiness, settings, storage, platform, fallbackCalculator };
65
65
  ctx.syncManager = syncManagerFactory && syncManagerFactory(ctx as ISdkFactoryContextSync);
66
66
 
67
67
  // SDK client and manager
@@ -2,9 +2,9 @@ import { IIntegrationManager, IIntegrationFactoryParams } from '../integrations/
2
2
  import { ISignalListener } from '../listeners/types';
3
3
  import { IReadinessManager, ISdkReadinessManager } from '../readiness/types';
4
4
  import type { sdkManagerFactory } from '../sdkManager';
5
- import type { splitApiFactory } from '../services/splitApi';
5
+ import { serviceApiFactory } from '../services/serviceApi';
6
6
  import type { IFallbackCalculator } from '../evaluator/fallbackTreatmentsCalculator';
7
- import { IFetch, ISplitApi, IEventSourceConstructor } from '../services/types';
7
+ import { IFetch, IServiceApi, IEventSourceConstructor } from '../services/types';
8
8
  import { IStorageAsync, IStorageSync, IStorageFactoryParams } from '../storages/types';
9
9
  import { ISyncManager } from '../sync/types';
10
10
  import { IImpressionObserver } from '../trackers/impressionObserver/types';
@@ -55,7 +55,7 @@ export interface ISdkFactoryContext {
55
55
  eventTracker: IEventTracker,
56
56
  telemetryTracker: ITelemetryTracker,
57
57
  storage: IStorageSync | IStorageAsync,
58
- splitApi?: ISplitApi,
58
+ serviceApi?: IServiceApi,
59
59
  syncManager?: ISyncManager,
60
60
  clients: Record<string, SplitIO.IBasicClient>,
61
61
  fallbackCalculator: IFallbackCalculator,
@@ -64,13 +64,13 @@ export interface ISdkFactoryContext {
64
64
 
65
65
  export interface ISdkFactoryContextSync extends ISdkFactoryContext {
66
66
  storage: IStorageSync,
67
- splitApi: ISplitApi
67
+ serviceApi: IServiceApi
68
68
  syncManager: ISyncManager,
69
69
  }
70
70
 
71
71
  export interface ISdkFactoryContextAsync extends ISdkFactoryContext {
72
72
  storage: IStorageAsync,
73
- splitApi: undefined,
73
+ serviceApi: undefined,
74
74
  syncManager: undefined
75
75
  }
76
76
 
@@ -91,9 +91,9 @@ export interface ISdkFactoryParams {
91
91
  // sync SDK (`IBrowserSDK` and `ISDK`) with `IStorageSync`, and async SDK (`IBrowserAsyncSDK` and `IAsyncSDK`) with `IStorageAsync`
92
92
  storageFactory: (params: IStorageFactoryParams) => IStorageSync | IStorageAsync,
93
93
 
94
- // Factory of Split Api (HTTP Client Service).
94
+ // Factory of ServiceApi (HTTP Client Service).
95
95
  // It is not required when providing an asynchronous storage or offline SyncManager
96
- splitApiFactory?: typeof splitApiFactory,
96
+ serviceApiFactory?: typeof serviceApiFactory,
97
97
 
98
98
  // SyncManager factory.
99
99
  // Not required when providing an asynchronous storage (consumer mode), but required in standalone mode to avoid SDK timeout.