@splitsoftware/splitio-commons 3.0.0-rc.3 → 3.0.0-rc.4
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/CHANGES.txt +1 -1
- package/cjs/logger/messages/debug.js +1 -1
- package/cjs/services/authProvider.js +1 -1
- package/cjs/services/decorateHeaders.js +2 -1
- package/cjs/services/secureSplitHttpClient.js +1 -1
- package/cjs/services/splitHttpClient.js +3 -5
- package/cjs/sync/polling/updaters/definitionChangesUpdater.js +8 -8
- package/esm/logger/messages/debug.js +1 -1
- package/esm/services/authProvider.js +1 -1
- package/esm/services/decorateHeaders.js +2 -1
- package/esm/services/secureSplitHttpClient.js +1 -1
- package/esm/services/splitHttpClient.js +3 -5
- package/esm/sync/polling/updaters/definitionChangesUpdater.js +8 -8
- package/package.json +1 -1
- package/src/logger/messages/debug.ts +1 -1
- package/src/services/authProvider.ts +1 -1
- package/src/services/decorateHeaders.ts +2 -1
- package/src/services/secureSplitHttpClient.ts +1 -1
- package/src/services/splitHttpClient.ts +7 -4
- package/src/services/types.ts +1 -1
- package/src/storages/types.ts +3 -3
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +9 -9
- package/types/splitio.d.ts +5 -5
package/CHANGES.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
3.0.0 (
|
|
1
|
+
3.0.0 (June XX, 2026)
|
|
2
2
|
- Extracted SDK lifecycle methods (`init`, `flush`, and `destroy`) into a reusable `sdkLifecycle` module.
|
|
3
3
|
- Extracted the `track` method into a standalone `trackMethod` factory for reuse across SDKs.
|
|
4
4
|
- Added a bloom filter utility and platform-specific modules (`src/platform/`) for reuse across SDKs.
|
|
@@ -25,7 +25,7 @@ exports.codesDebug = info_1.codesInfo.concat([
|
|
|
25
25
|
// synchronizer
|
|
26
26
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
|
|
27
27
|
[c.SYNC_FETCH, c.LOG_PREFIX_SYNC + 'Spin up %s updates using since = %s and rbSince = %s.'],
|
|
28
|
-
[c.SYNC_UPDATE, c.LOG_PREFIX_SYNC + '
|
|
28
|
+
[c.SYNC_UPDATE, c.LOG_PREFIX_SYNC + 'Updated %s: %s. Removed: %s.'],
|
|
29
29
|
[c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
|
|
30
30
|
[c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + 'Starting %s. Running each %s millis'],
|
|
31
31
|
[c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + 'Running %s'],
|
|
@@ -17,7 +17,7 @@ function authProviderFactory(settings, splitHttpClient, telemetryTracker) {
|
|
|
17
17
|
var urls = settings.urls, log = settings.log;
|
|
18
18
|
function fetchAuth() {
|
|
19
19
|
var url = "".concat(urls.auth, "/v3/auth?capabilities=config");
|
|
20
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_2.TOKEN));
|
|
20
|
+
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(constants_2.TOKEN), false, true);
|
|
21
21
|
}
|
|
22
22
|
var authenticate = (0, AuthClient_1.authenticateFactory)(fetchAuth);
|
|
23
23
|
var backoff = new Backoff_1.Backoff(fetchCredential);
|
|
@@ -16,7 +16,7 @@ function secureSplitHttpClientFactory(settings, platform, telemetryTracker) {
|
|
|
16
16
|
var splitHttpClient = (0, splitHttpClient_1.splitHttpClientFactory)(settings, platform);
|
|
17
17
|
var authProvider = (0, authProvider_1.authProviderFactory)(settings, splitHttpClient, telemetryTracker);
|
|
18
18
|
function makeRequest(url, options, latencyTracker, logErrorsAsInfo, token) {
|
|
19
|
-
return splitHttpClient(url, tslib_1.__assign(tslib_1.__assign({}, options), { headers: tslib_1.__assign(tslib_1.__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo);
|
|
19
|
+
return splitHttpClient(url, tslib_1.__assign(tslib_1.__assign({}, options), { headers: tslib_1.__assign(tslib_1.__assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: "Bearer ".concat(token) }) }), latencyTracker, logErrorsAsInfo, true);
|
|
20
20
|
}
|
|
21
21
|
var httpClient = function (url, options, latencyTracker, logErrorsAsInfo) {
|
|
22
22
|
return authProvider.credential().then(function (credential) {
|
|
@@ -24,19 +24,17 @@ function splitHttpClientFactory(settings, _a) {
|
|
|
24
24
|
var commonHeaders = {
|
|
25
25
|
'Accept': 'application/json',
|
|
26
26
|
'Content-Type': 'application/json',
|
|
27
|
-
'Authorization': "Bearer ".concat(authorizationKey)
|
|
28
|
-
'SplitSDKVersion': version
|
|
27
|
+
'Authorization': "Bearer ".concat(authorizationKey)
|
|
29
28
|
};
|
|
30
29
|
if (ip)
|
|
31
30
|
commonHeaders['SplitSDKMachineIP'] = ip;
|
|
32
31
|
if (hostname)
|
|
33
32
|
commonHeaders['SplitSDKMachineName'] = (0, decorateHeaders_1.removeNonISO88591)(hostname);
|
|
34
|
-
return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo) {
|
|
33
|
+
return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo, newVersionHeader) {
|
|
35
34
|
if (reqOpts === void 0) { reqOpts = {}; }
|
|
36
35
|
if (latencyTracker === void 0) { latencyTracker = function () { }; }
|
|
37
|
-
if (logErrorsAsInfo === void 0) { logErrorsAsInfo = false; }
|
|
38
36
|
var request = (0, objectAssign_1.objectAssign)({
|
|
39
|
-
headers: (0, decorateHeaders_1.decorateHeaders)(settings, (0, objectAssign_1.objectAssign)({}, commonHeaders, reqOpts.headers || {})),
|
|
37
|
+
headers: (0, decorateHeaders_1.decorateHeaders)(settings, (0, objectAssign_1.objectAssign)(newVersionHeader ? { 'X-Harness-FME-SDK-Version': version } : { 'SplitSDKVersion': version }, commonHeaders, reqOpts.headers || {})),
|
|
40
38
|
method: reqOpts.method || 'GET',
|
|
41
39
|
body: reqOpts.body
|
|
42
40
|
}, options);
|
|
@@ -73,7 +73,7 @@ function matchFilters(definition, filters) {
|
|
|
73
73
|
function computeMutation(update, segments, filters) {
|
|
74
74
|
return update.updated.reduce(function (accum, ruleEntity) {
|
|
75
75
|
if (!filters || matchFilters(ruleEntity, filters)) {
|
|
76
|
-
accum.
|
|
76
|
+
accum.updated.push(ruleEntity);
|
|
77
77
|
parseSegments(ruleEntity).forEach(function (segmentName) {
|
|
78
78
|
segments.add(segmentName);
|
|
79
79
|
});
|
|
@@ -83,7 +83,7 @@ function computeMutation(update, segments, filters) {
|
|
|
83
83
|
}
|
|
84
84
|
accum.names.push(ruleEntity.name);
|
|
85
85
|
return accum;
|
|
86
|
-
}, {
|
|
86
|
+
}, { updated: [], removed: update.removed, names: update.removed.slice() });
|
|
87
87
|
}
|
|
88
88
|
exports.computeMutation = computeMutation;
|
|
89
89
|
function convertInstantUpdateToDefinitionChanges(instantUpdate) {
|
|
@@ -148,16 +148,16 @@ function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage,
|
|
|
148
148
|
var updatedDefinitions = [];
|
|
149
149
|
var ffUpdate = false;
|
|
150
150
|
if (definitionChanges.d) {
|
|
151
|
-
var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation),
|
|
151
|
+
var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), updated = _a.updated, removed = _a.removed, names = _a.names;
|
|
152
152
|
updatedDefinitions = names;
|
|
153
|
-
log.debug(constants_2.SYNC_UPDATE, [definitionChangesFetcher.type,
|
|
154
|
-
ffUpdate = definitions.update(
|
|
153
|
+
log.debug(constants_2.SYNC_UPDATE, [definitionChangesFetcher.type, updated.length, removed.length]);
|
|
154
|
+
ffUpdate = definitions.update(updated, removed, definitionChanges.d.till);
|
|
155
155
|
}
|
|
156
156
|
var rbsUpdate = false;
|
|
157
157
|
if (definitionChanges.rbs) {
|
|
158
|
-
var _b = computeMutation(definitionChanges.rbs, usedSegments),
|
|
159
|
-
log.debug(constants_2.SYNC_UPDATE, ['rule-based segments',
|
|
160
|
-
rbsUpdate = rbSegments.update(
|
|
158
|
+
var _b = computeMutation(definitionChanges.rbs, usedSegments), updated = _b.updated, removed = _b.removed;
|
|
159
|
+
log.debug(constants_2.SYNC_UPDATE, ['rule-based segments', updated.length, removed.length]);
|
|
160
|
+
rbsUpdate = rbSegments.update(updated, removed, definitionChanges.rbs.till);
|
|
161
161
|
}
|
|
162
162
|
return Promise.all([ffUpdate, rbsUpdate,
|
|
163
163
|
// @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
|
|
@@ -21,7 +21,7 @@ export var codesDebug = codesInfo.concat([
|
|
|
21
21
|
// synchronizer
|
|
22
22
|
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
|
|
23
23
|
[c.SYNC_FETCH, c.LOG_PREFIX_SYNC + 'Spin up %s updates using since = %s and rbSince = %s.'],
|
|
24
|
-
[c.SYNC_UPDATE, c.LOG_PREFIX_SYNC + '
|
|
24
|
+
[c.SYNC_UPDATE, c.LOG_PREFIX_SYNC + 'Updated %s: %s. Removed: %s.'],
|
|
25
25
|
[c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
|
|
26
26
|
[c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + 'Starting %s. Running each %s millis'],
|
|
27
27
|
[c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + 'Running %s'],
|
|
@@ -14,7 +14,7 @@ export function authProviderFactory(settings, splitHttpClient, telemetryTracker)
|
|
|
14
14
|
var urls = settings.urls, log = settings.log;
|
|
15
15
|
function fetchAuth() {
|
|
16
16
|
var url = "".concat(urls.auth, "/v3/auth?capabilities=config");
|
|
17
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
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);
|
|
@@ -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) {
|
|
@@ -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);
|
|
@@ -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.
|
|
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
|
-
}, {
|
|
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),
|
|
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,
|
|
149
|
-
ffUpdate = definitions.update(
|
|
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),
|
|
154
|
-
log.debug(SYNC_UPDATE, ['rule-based segments',
|
|
155
|
-
rbsUpdate = rbSegments.update(
|
|
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
|
package/package.json
CHANGED
|
@@ -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 + '
|
|
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'],
|
|
@@ -29,7 +29,7 @@ export function authProviderFactory(settings: ISettings, splitHttpClient: ISplit
|
|
|
29
29
|
|
|
30
30
|
function fetchAuth() {
|
|
31
31
|
let url = `${urls.auth}/v3/auth?capabilities=config`;
|
|
32
|
-
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN));
|
|
32
|
+
return splitHttpClient(url, undefined, telemetryTracker.trackHttp(TOKEN), false, true);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
const authenticate = authenticateFactory(fetchAuth);
|
|
@@ -14,7 +14,8 @@ const FORBIDDEN_HEADERS = new Set([
|
|
|
14
14
|
'content-encoding',
|
|
15
15
|
'accept',
|
|
16
16
|
'keep-alive',
|
|
17
|
-
'x-fastly-debug'
|
|
17
|
+
'x-fastly-debug',
|
|
18
|
+
'x-harness-fme-sdk-version'
|
|
18
19
|
]);
|
|
19
20
|
|
|
20
21
|
export function decorateHeaders(settings: ISettings, headers: Record<string, string>) {
|
|
@@ -19,7 +19,7 @@ export function secureSplitHttpClientFactory(settings: ISettings, platform: Pick
|
|
|
19
19
|
const authProvider = authProviderFactory(settings, splitHttpClient, telemetryTracker);
|
|
20
20
|
|
|
21
21
|
function makeRequest(url: string, options: IRequestOptions | undefined, latencyTracker: ((error?: NetworkError) => void) | undefined, logErrorsAsInfo: boolean | undefined, token: string): Promise<IResponse> {
|
|
22
|
-
return splitHttpClient(url, { ...options, headers: { ...options?.headers, Authorization: `Bearer ${token}` } }, latencyTracker, logErrorsAsInfo);
|
|
22
|
+
return splitHttpClient(url, { ...options, headers: { ...options?.headers, Authorization: `Bearer ${token}` } }, latencyTracker, logErrorsAsInfo, true);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
const httpClient = function (url: string, options?: IRequestOptions, latencyTracker?: (error?: NetworkError) => void, logErrorsAsInfo?: boolean): Promise<IResponse> {
|
|
@@ -27,17 +27,20 @@ export function splitHttpClientFactory(settings: ISettings, { getOptions, getFet
|
|
|
27
27
|
const commonHeaders: Record<string, string> = {
|
|
28
28
|
'Accept': 'application/json',
|
|
29
29
|
'Content-Type': 'application/json',
|
|
30
|
-
'Authorization': `Bearer ${authorizationKey}
|
|
31
|
-
'SplitSDKVersion': version
|
|
30
|
+
'Authorization': `Bearer ${authorizationKey}`
|
|
32
31
|
};
|
|
33
32
|
|
|
34
33
|
if (ip) commonHeaders['SplitSDKMachineIP'] = ip;
|
|
35
34
|
if (hostname) commonHeaders['SplitSDKMachineName'] = removeNonISO88591(hostname);
|
|
36
35
|
|
|
37
|
-
return function httpClient(url: string, reqOpts: IRequestOptions = {}, latencyTracker: (error?: NetworkError) => void = () => { }, logErrorsAsInfo
|
|
36
|
+
return function httpClient(url: string, reqOpts: IRequestOptions = {}, latencyTracker: (error?: NetworkError) => void = () => { }, logErrorsAsInfo?: boolean, newVersionHeader?: boolean): Promise<IResponse> {
|
|
38
37
|
|
|
39
38
|
const request = objectAssign({
|
|
40
|
-
headers: decorateHeaders(settings, objectAssign(
|
|
39
|
+
headers: decorateHeaders(settings, objectAssign(
|
|
40
|
+
newVersionHeader ? { 'X-Harness-FME-SDK-Version': version } : { 'SplitSDKVersion': version },
|
|
41
|
+
commonHeaders,
|
|
42
|
+
reqOpts.headers || {}
|
|
43
|
+
)),
|
|
41
44
|
method: reqOpts.method || 'GET',
|
|
42
45
|
body: reqOpts.body
|
|
43
46
|
}, options);
|
package/src/services/types.ts
CHANGED
|
@@ -31,7 +31,7 @@ export type IFetch = (url: string, options?: IRequestOptions) => Promise<IRespon
|
|
|
31
31
|
// IFetch specialization
|
|
32
32
|
export type IHealthCheckAPI = () => Promise<boolean>
|
|
33
33
|
|
|
34
|
-
export type ISplitHttpClient = (url: string, options?: IRequestOptions, latencyTracker?: (error?: NetworkError) => void, logErrorsAsInfo?: boolean) => Promise<IResponse>
|
|
34
|
+
export type ISplitHttpClient = (url: string, options?: IRequestOptions, latencyTracker?: (error?: NetworkError) => void, logErrorsAsInfo?: boolean, newVersionHeader?: boolean) => Promise<IResponse>
|
|
35
35
|
|
|
36
36
|
export type ISecureSplitHttpClient = ISplitHttpClient & { stop(): void }
|
|
37
37
|
|
package/src/storages/types.ts
CHANGED
|
@@ -195,7 +195,7 @@ export interface IPluggableStorageWrapper {
|
|
|
195
195
|
/** Splits cache */
|
|
196
196
|
|
|
197
197
|
export interface IDefinitionsCacheBase {
|
|
198
|
-
update(
|
|
198
|
+
update(toUpsert: IDefinition[], toRemove: string[], changeNumber: number): MaybeThenable<boolean>,
|
|
199
199
|
get(name: string): MaybeThenable<IDefinition | null>,
|
|
200
200
|
getMany(names: string[]): MaybeThenable<Record<string, IDefinition | null>>, // `fetchMany` in spec
|
|
201
201
|
// should never reject or throw an exception. Instead return -1 by default, assuming no splits are present in the storage.
|
|
@@ -212,7 +212,7 @@ export interface IDefinitionsCacheBase {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
export interface IDefinitionsCacheSync extends IDefinitionsCacheBase {
|
|
215
|
-
update(
|
|
215
|
+
update(toUpsert: IDefinition[], toRemove: string[], changeNumber: number): boolean,
|
|
216
216
|
get(name: string): IDefinition | null,
|
|
217
217
|
getMany(names: string[]): Record<string, IDefinition | null>,
|
|
218
218
|
getChangeNumber(): number,
|
|
@@ -226,7 +226,7 @@ export interface IDefinitionsCacheSync extends IDefinitionsCacheBase {
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
export interface IDefinitionsCacheAsync extends IDefinitionsCacheBase {
|
|
229
|
-
update(
|
|
229
|
+
update(toUpsert: IDefinition[], toRemove: string[], changeNumber: number): Promise<boolean>,
|
|
230
230
|
get(name: string): Promise<IDefinition | null>,
|
|
231
231
|
getMany(names: string[]): Promise<Record<string, IDefinition | null>>,
|
|
232
232
|
getChangeNumber(): Promise<number>,
|
|
@@ -57,7 +57,7 @@ export function parseSegments(ruleEntity: IDefinition | IRBSegment, matcherType:
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
interface IDefinitionMutations<T extends IDefinition | IRBSegment> {
|
|
60
|
-
|
|
60
|
+
updated: T[],
|
|
61
61
|
removed: string[],
|
|
62
62
|
names: string[]
|
|
63
63
|
}
|
|
@@ -91,7 +91,7 @@ function matchFilters(definition: IDefinition, filters: ISplitFiltersValidation)
|
|
|
91
91
|
export function computeMutation<T extends IDefinition | IRBSegment>(update: { updated: T[], removed: string[] }, segments: Set<string>, filters?: ISplitFiltersValidation): IDefinitionMutations<T> {
|
|
92
92
|
return update.updated.reduce((accum, ruleEntity) => {
|
|
93
93
|
if (!filters || matchFilters(ruleEntity as IDefinition, filters)) {
|
|
94
|
-
accum.
|
|
94
|
+
accum.updated.push(ruleEntity);
|
|
95
95
|
|
|
96
96
|
parseSegments(ruleEntity).forEach((segmentName: string) => {
|
|
97
97
|
segments.add(segmentName);
|
|
@@ -101,7 +101,7 @@ export function computeMutation<T extends IDefinition | IRBSegment>(update: { up
|
|
|
101
101
|
}
|
|
102
102
|
accum.names.push(ruleEntity.name);
|
|
103
103
|
return accum;
|
|
104
|
-
}, {
|
|
104
|
+
}, { updated: [], removed: update.removed, names: update.removed.slice() } as IDefinitionMutations<T>);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function convertInstantUpdateToDefinitionChanges(instantUpdate: InstantUpdate) {
|
|
@@ -180,17 +180,17 @@ export function definitionChangesUpdaterFactory(
|
|
|
180
180
|
let updatedDefinitions: string[] = [];
|
|
181
181
|
let ffUpdate: MaybeThenable<boolean> = false;
|
|
182
182
|
if (definitionChanges.d) {
|
|
183
|
-
const {
|
|
183
|
+
const { updated, removed, names } = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation);
|
|
184
184
|
updatedDefinitions = names;
|
|
185
|
-
log.debug(SYNC_UPDATE, [definitionChangesFetcher.type,
|
|
186
|
-
ffUpdate = definitions.update(
|
|
185
|
+
log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, updated.length, removed.length]);
|
|
186
|
+
ffUpdate = definitions.update(updated, removed, definitionChanges.d.till);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
let rbsUpdate: MaybeThenable<boolean> = false;
|
|
190
190
|
if (definitionChanges.rbs) {
|
|
191
|
-
const {
|
|
192
|
-
log.debug(SYNC_UPDATE, ['rule-based segments',
|
|
193
|
-
rbsUpdate = rbSegments.update(
|
|
191
|
+
const { updated, removed } = computeMutation(definitionChanges.rbs, usedSegments);
|
|
192
|
+
log.debug(SYNC_UPDATE, ['rule-based segments', updated.length, removed.length]);
|
|
193
|
+
rbsUpdate = rbSegments.update(updated, removed, definitionChanges.rbs.till);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
return Promise.all([ffUpdate, rbsUpdate,
|
package/types/splitio.d.ts
CHANGED
|
@@ -213,7 +213,7 @@ interface IServerSideSharedSettings {
|
|
|
213
213
|
*/
|
|
214
214
|
startup?: {
|
|
215
215
|
/**
|
|
216
|
-
* Time in seconds
|
|
216
|
+
* Time in seconds before emitting the `SDK_READY_TIMED_OUT` event.
|
|
217
217
|
*
|
|
218
218
|
* @defaultValue `15`
|
|
219
219
|
*/
|
|
@@ -373,7 +373,7 @@ interface IClientSideSyncSharedSettings extends IClientSideSharedSettings, ISync
|
|
|
373
373
|
*/
|
|
374
374
|
startup?: {
|
|
375
375
|
/**
|
|
376
|
-
* Time in seconds
|
|
376
|
+
* Time in seconds before emitting the `SDK_READY_TIMED_OUT` event.
|
|
377
377
|
*
|
|
378
378
|
* @defaultValue `10`
|
|
379
379
|
*/
|
|
@@ -1439,7 +1439,7 @@ declare namespace SplitIO {
|
|
|
1439
1439
|
*/
|
|
1440
1440
|
startup?: {
|
|
1441
1441
|
/**
|
|
1442
|
-
* Time in seconds
|
|
1442
|
+
* Time in seconds before emitting the `SDK_READY_TIMED_OUT` event.
|
|
1443
1443
|
*
|
|
1444
1444
|
* @defaultValue `10`
|
|
1445
1445
|
*/
|
|
@@ -2341,8 +2341,8 @@ declare namespace SplitIO {
|
|
|
2341
2341
|
*/
|
|
2342
2342
|
logLevel?: LogLevel;
|
|
2343
2343
|
/**
|
|
2344
|
-
* Time in seconds
|
|
2345
|
-
* A value of
|
|
2344
|
+
* Time in seconds before emitting the `SDK_READY_TIMED_OUT` event.
|
|
2345
|
+
* A value of `-1` disables the timeout and thus the event is never emitted.
|
|
2346
2346
|
*
|
|
2347
2347
|
* @defaultValue `10`
|
|
2348
2348
|
*/
|