@splitsoftware/splitio-commons 1.16.0 → 1.16.1-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +3 -0
- package/cjs/evaluator/matchers/index.js +3 -1
- package/cjs/evaluator/matchers/large_segment.js +16 -0
- package/cjs/evaluator/matchers/matcherTypes.js +1 -0
- package/cjs/evaluator/matchersTransform/index.js +1 -1
- package/cjs/logger/constants.js +4 -4
- package/cjs/logger/messages/info.js +0 -1
- package/cjs/readiness/readinessManager.js +14 -10
- package/cjs/readiness/sdkReadinessManager.js +5 -6
- package/cjs/sdkClient/sdkClientMethodCS.js +3 -4
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +4 -5
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/services/splitApi.js +4 -0
- package/cjs/storages/AbstractSplitsCacheAsync.js +2 -2
- package/cjs/storages/AbstractSplitsCacheSync.js +5 -5
- package/cjs/storages/KeyBuilder.js +3 -0
- package/cjs/storages/KeyBuilderCS.js +17 -5
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +16 -4
- package/cjs/storages/inLocalStorage/index.js +6 -2
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +20 -11
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +5 -1
- package/cjs/sync/polling/pollingManagerCS.js +51 -33
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +5 -6
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +2 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -0
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +15 -5
- package/cjs/sync/streaming/constants.js +2 -1
- package/cjs/sync/streaming/pushManager.js +95 -64
- package/cjs/sync/submitters/telemetrySubmitter.js +2 -0
- package/cjs/sync/syncManagerOnline.js +24 -14
- package/cjs/utils/constants/index.js +5 -1
- package/cjs/utils/settingsValidation/index.js +9 -4
- package/esm/evaluator/matchers/index.js +3 -1
- package/esm/evaluator/matchers/large_segment.js +12 -0
- package/esm/evaluator/matchers/matcherTypes.js +1 -0
- package/esm/evaluator/matchersTransform/index.js +1 -1
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/info.js +0 -1
- package/esm/readiness/readinessManager.js +14 -10
- package/esm/readiness/sdkReadinessManager.js +5 -6
- package/esm/sdkClient/sdkClientMethodCS.js +4 -5
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +5 -6
- package/esm/sdkFactory/index.js +1 -1
- package/esm/services/splitApi.js +5 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +2 -2
- package/esm/storages/AbstractSplitsCacheSync.js +3 -3
- package/esm/storages/KeyBuilder.js +3 -0
- package/esm/storages/KeyBuilderCS.js +15 -4
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +17 -5
- package/esm/storages/inLocalStorage/index.js +7 -3
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/esm/storages/inMemory/SplitsCacheInMemory.js +21 -12
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +5 -1
- package/esm/sync/polling/pollingManagerCS.js +52 -34
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -4
- package/esm/sync/polling/updaters/splitChangesUpdater.js +2 -1
- package/esm/sync/streaming/SSEHandler/index.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +15 -5
- package/esm/sync/streaming/constants.js +1 -0
- package/esm/sync/streaming/pushManager.js +95 -65
- package/esm/sync/submitters/telemetrySubmitter.js +2 -0
- package/esm/sync/syncManagerOnline.js +25 -15
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/settingsValidation/index.js +10 -5
- package/package.json +1 -1
- package/src/dtos/types.ts +17 -7
- package/src/evaluator/matchers/index.ts +2 -0
- package/src/evaluator/matchers/large_segment.ts +18 -0
- package/src/evaluator/matchers/matcherTypes.ts +1 -0
- package/src/evaluator/matchersTransform/index.ts +1 -1
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/info.ts +0 -1
- package/src/readiness/readinessManager.ts +13 -9
- package/src/readiness/sdkReadinessManager.ts +7 -7
- package/src/readiness/types.ts +3 -2
- package/src/sdkClient/sdkClientMethodCS.ts +4 -6
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +5 -7
- package/src/sdkFactory/index.ts +1 -1
- package/src/services/splitApi.ts +6 -1
- package/src/services/types.ts +1 -0
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -2
- package/src/storages/AbstractSplitsCacheSync.ts +4 -4
- package/src/storages/KeyBuilder.ts +3 -0
- package/src/storages/KeyBuilderCS.ts +25 -5
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +3 -3
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +20 -5
- package/src/storages/inLocalStorage/index.ts +8 -4
- package/src/storages/inMemory/InMemoryStorageCS.ts +5 -0
- package/src/storages/inMemory/SplitsCacheInMemory.ts +15 -10
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +7 -11
- package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
- package/src/storages/types.ts +7 -5
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +6 -2
- package/src/sync/polling/pollingManagerCS.ts +61 -29
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +10 -10
- package/src/sync/polling/types.ts +3 -2
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +5 -8
- package/src/sync/polling/updaters/splitChangesUpdater.ts +4 -3
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +14 -2
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +17 -5
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +100 -63
- package/src/sync/streaming/types.ts +5 -3
- package/src/sync/submitters/telemetrySubmitter.ts +2 -0
- package/src/sync/submitters/types.ts +10 -4
- package/src/sync/syncManagerOnline.ts +19 -11
- package/src/types.ts +26 -1
- package/src/utils/constants/index.ts +5 -0
- package/src/utils/settingsValidation/index.ts +11 -6
- package/src/utils/settingsValidation/types.ts +1 -1
- package/types/dtos/types.d.ts +14 -6
- package/types/evaluator/matchers/large_segment.d.ts +5 -0
- package/types/logger/constants.d.ts +1 -1
- package/types/readiness/readinessManager.d.ts +2 -2
- package/types/readiness/sdkReadinessManager.d.ts +2 -3
- package/types/readiness/types.d.ts +3 -2
- package/types/services/types.d.ts +1 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +3 -3
- package/types/storages/KeyBuilder.d.ts +1 -0
- package/types/storages/KeyBuilderCS.d.ts +7 -2
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +3 -2
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +4 -6
- package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
- package/types/storages/types.d.ts +4 -3
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -3
- package/types/sync/polling/types.d.ts +9 -2
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +4 -4
- package/types/sync/streaming/SSEHandler/types.d.ts +13 -2
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/constants.d.ts +1 -0
- package/types/sync/streaming/pushManager.d.ts +2 -0
- package/types/sync/streaming/types.d.ts +5 -4
- package/types/sync/submitters/types.d.ts +9 -3
- package/types/types.d.ts +25 -0
- package/types/utils/constants/index.d.ts +3 -0
- package/types/utils/settingsValidation/index.d.ts +2 -0
- package/types/utils/settingsValidation/types.d.ts +1 -1
|
@@ -8,13 +8,19 @@ import { authenticateFactory, hashUserKey } from './AuthClient';
|
|
|
8
8
|
import { forOwn } from '../../utils/lang';
|
|
9
9
|
import { SSEClient } from './SSEClient';
|
|
10
10
|
import { getMatching } from '../../utils/key';
|
|
11
|
-
import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
11
|
+
import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType, MY_LARGE_SEGMENTS_UPDATE } from './constants';
|
|
12
12
|
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
|
|
13
13
|
import { UpdateStrategy } from './SSEHandler/types';
|
|
14
14
|
import { isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
|
|
15
15
|
import { _Set } from '../../utils/lang/sets';
|
|
16
|
+
import { hash } from '../../utils/murmur3/murmur3';
|
|
16
17
|
import { hash64 } from '../../utils/murmur3/murmur3_64';
|
|
17
|
-
import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
18
|
+
import { TOKEN_REFRESH, AUTH_REJECTION, MY_LARGE_SEGMENT, MY_SEGMENT } from '../../utils/constants';
|
|
19
|
+
export function getDelay(parsedData, matchingKey) {
|
|
20
|
+
var interval = parsedData.i || 60000;
|
|
21
|
+
var seed = parsedData.s || 0;
|
|
22
|
+
return hash(matchingKey, seed) % interval;
|
|
23
|
+
}
|
|
18
24
|
/**
|
|
19
25
|
* PushManager factory:
|
|
20
26
|
* - for server-side if key is not provided in settings.
|
|
@@ -140,8 +146,9 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
140
146
|
splitsUpdateWorker.stop();
|
|
141
147
|
if (userKey)
|
|
142
148
|
forOwn(clients, function (_a) {
|
|
143
|
-
var worker = _a.worker;
|
|
144
|
-
|
|
149
|
+
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
150
|
+
worker.stop();
|
|
151
|
+
workerLarge && workerLarge.stop();
|
|
145
152
|
});
|
|
146
153
|
else
|
|
147
154
|
segmentsUpdateWorker.stop();
|
|
@@ -195,77 +202,96 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
195
202
|
}
|
|
196
203
|
splitsUpdateWorker.put(parsedData);
|
|
197
204
|
});
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
});
|
|
206
|
-
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, function handleMySegmentsUpdate(parsedData) {
|
|
207
|
-
switch (parsedData.u) {
|
|
208
|
-
case UpdateStrategy.BoundedFetchRequest: {
|
|
209
|
-
var bitmap_1;
|
|
210
|
-
try {
|
|
211
|
-
bitmap_1 = parseBitmap(parsedData.d, parsedData.c);
|
|
212
|
-
}
|
|
213
|
-
catch (e) {
|
|
214
|
-
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
215
|
-
break;
|
|
216
|
-
}
|
|
217
|
-
forOwn(clients, function (_a) {
|
|
218
|
-
var hash64 = _a.hash64, worker = _a.worker;
|
|
219
|
-
if (isInBitmap(bitmap_1, hash64.hex)) {
|
|
220
|
-
worker.put(parsedData.changeNumber); // fetch mySegments
|
|
221
|
-
}
|
|
222
|
-
});
|
|
223
|
-
return;
|
|
205
|
+
function handleMySegmentsUpdate(parsedData) {
|
|
206
|
+
var isLS = parsedData.type === MY_LARGE_SEGMENTS_UPDATE;
|
|
207
|
+
switch (parsedData.u) {
|
|
208
|
+
case UpdateStrategy.BoundedFetchRequest: {
|
|
209
|
+
var bitmap_1;
|
|
210
|
+
try {
|
|
211
|
+
bitmap_1 = parseBitmap(parsedData.d, parsedData.c);
|
|
224
212
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
213
|
+
catch (e) {
|
|
214
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
forOwn(clients, function (_a, matchingKey) {
|
|
218
|
+
var hash64 = _a.hash64, worker = _a.worker, workerLarge = _a.workerLarge;
|
|
219
|
+
if (isInBitmap(bitmap_1, hash64.hex)) {
|
|
220
|
+
isLS ?
|
|
221
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
222
|
+
worker.put(parsedData.changeNumber);
|
|
235
223
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
224
|
+
});
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
case UpdateStrategy.KeyList: {
|
|
228
|
+
var keyList = void 0, added_1, removed_1;
|
|
229
|
+
try {
|
|
230
|
+
keyList = parseKeyList(parsedData.d, parsedData.c);
|
|
231
|
+
added_1 = new _Set(keyList.a);
|
|
232
|
+
removed_1 = new _Set(keyList.r);
|
|
233
|
+
}
|
|
234
|
+
catch (e) {
|
|
235
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['KeyList', e]);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
forOwn(clients, function (_a) {
|
|
239
|
+
var hash64 = _a.hash64, worker = _a.worker, workerLarge = _a.workerLarge;
|
|
240
|
+
var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
|
|
241
|
+
if (add !== undefined) {
|
|
242
|
+
isLS ?
|
|
243
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, {
|
|
244
|
+
name: parsedData.largeSegments[0],
|
|
245
|
+
add: add
|
|
246
|
+
}) :
|
|
240
247
|
worker.put(parsedData.changeNumber, {
|
|
241
248
|
name: parsedData.segmentName,
|
|
242
249
|
add: add
|
|
243
250
|
});
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
case UpdateStrategy.SegmentRemoval:
|
|
249
|
-
if (!parsedData.segmentName) {
|
|
250
|
-
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
251
|
-
break;
|
|
252
251
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
});
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
case UpdateStrategy.SegmentRemoval:
|
|
256
|
+
if ((isLS && parsedData.largeSegments.length === 0) || (!isLS && !parsedData.segmentName)) {
|
|
257
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
forOwn(clients, function (_a) {
|
|
261
|
+
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
262
|
+
isLS ?
|
|
263
|
+
workerLarge && parsedData.largeSegments.forEach(function (largeSegment) {
|
|
264
|
+
workerLarge.put(parsedData.changeNumber, {
|
|
265
|
+
name: largeSegment,
|
|
266
|
+
add: false
|
|
267
|
+
});
|
|
268
|
+
}) :
|
|
269
|
+
worker.put(parsedData.changeNumber, {
|
|
256
270
|
name: parsedData.segmentName,
|
|
257
271
|
add: false
|
|
258
272
|
});
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
273
|
+
});
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
// `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
|
|
277
|
+
forOwn(clients, function (_a, matchingKey) {
|
|
278
|
+
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
279
|
+
isLS ?
|
|
280
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
265
281
|
worker.put(parsedData.changeNumber);
|
|
266
|
-
});
|
|
267
282
|
});
|
|
268
283
|
}
|
|
284
|
+
if (userKey) {
|
|
285
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
|
|
286
|
+
var userKeyHash = channel.split('_')[2];
|
|
287
|
+
var userKey = userKeyHashes[userKeyHash];
|
|
288
|
+
if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
|
|
289
|
+
clients[userKey].worker.put(parsedData.changeNumber, parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, handleMySegmentsUpdate);
|
|
293
|
+
pushEmitter.on(MY_LARGE_SEGMENTS_UPDATE, handleMySegmentsUpdate);
|
|
294
|
+
}
|
|
269
295
|
else {
|
|
270
296
|
pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker.put);
|
|
271
297
|
}
|
|
@@ -287,7 +313,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
287
313
|
return;
|
|
288
314
|
disconnected = false;
|
|
289
315
|
if (userKey)
|
|
290
|
-
this.add(userKey, pollingManager.segmentsSyncTask); // client-side
|
|
316
|
+
this.add(userKey, pollingManager.segmentsSyncTask, pollingManager.largeSegmentsSyncTask); // client-side
|
|
291
317
|
else
|
|
292
318
|
setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
|
|
293
319
|
},
|
|
@@ -296,11 +322,15 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
296
322
|
return disconnected === false;
|
|
297
323
|
},
|
|
298
324
|
// [Only for client-side]
|
|
299
|
-
add: function (userKey, mySegmentsSyncTask) {
|
|
325
|
+
add: function (userKey, mySegmentsSyncTask, myLargeSegmentsSyncTask) {
|
|
300
326
|
var hash = hashUserKey(userKey);
|
|
301
327
|
if (!userKeyHashes[hash]) {
|
|
302
328
|
userKeyHashes[hash] = userKey;
|
|
303
|
-
clients[userKey] = {
|
|
329
|
+
clients[userKey] = {
|
|
330
|
+
hash64: hash64(userKey),
|
|
331
|
+
worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker, MY_SEGMENT),
|
|
332
|
+
workerLarge: myLargeSegmentsSyncTask ? MySegmentsUpdateWorker(myLargeSegmentsSyncTask, telemetryTracker, MY_LARGE_SEGMENT) : undefined
|
|
333
|
+
};
|
|
304
334
|
connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
|
|
305
335
|
// Reconnects in case of a new client.
|
|
306
336
|
// Run in next event-loop cycle to save authentication calls
|
|
@@ -61,10 +61,12 @@ export function telemetryCacheConfigAdapter(telemetry, settings) {
|
|
|
61
61
|
var _a = getTelemetryFlagSetsStats(settings.sync.__splitFiltersValidation), flagSetsTotal = _a.flagSetsTotal, flagSetsIgnored = _a.flagSetsIgnored;
|
|
62
62
|
return objectAssign(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
|
63
63
|
sE: settings.streamingEnabled,
|
|
64
|
+
lE: isClientSide ? settings.sync.largeSegmentsEnabled : undefined,
|
|
64
65
|
rR: {
|
|
65
66
|
sp: scheduler.featuresRefreshRate / 1000,
|
|
66
67
|
se: isClientSide ? undefined : scheduler.segmentsRefreshRate / 1000,
|
|
67
68
|
ms: isClientSide ? scheduler.segmentsRefreshRate / 1000 : undefined,
|
|
69
|
+
mls: isClientSide && settings.sync.largeSegmentsEnabled ? scheduler.largeSegmentsRefreshRate / 1000 : undefined,
|
|
68
70
|
im: scheduler.impressionsRefreshRate / 1000,
|
|
69
71
|
ev: scheduler.eventsPushRate / 1000,
|
|
70
72
|
te: scheduler.telemetryRefreshRate / 1000,
|
|
@@ -2,7 +2,7 @@ import { submitterManagerFactory } from './submitters/submitterManager';
|
|
|
2
2
|
import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
3
3
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
4
4
|
import { isConsentGranted } from '../consent';
|
|
5
|
-
import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
5
|
+
import { IN_LARGE_SEGMENT, IN_SEGMENT, POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
6
6
|
/**
|
|
7
7
|
* Online SyncManager factory.
|
|
8
8
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -114,43 +114,53 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
114
114
|
shared: function (matchingKey, readinessManager, storage) {
|
|
115
115
|
if (!pollingManager)
|
|
116
116
|
return;
|
|
117
|
-
var
|
|
117
|
+
var _a = pollingManager.add(matchingKey, readinessManager, storage), msSyncTask = _a.msSyncTask, mlsSyncTask = _a.mlsSyncTask;
|
|
118
118
|
return {
|
|
119
|
-
isRunning:
|
|
119
|
+
isRunning: msSyncTask.isRunning,
|
|
120
120
|
start: function () {
|
|
121
121
|
if (syncEnabled) {
|
|
122
122
|
if (pushManager) {
|
|
123
123
|
if (pollingManager.isRunning()) {
|
|
124
124
|
// if doing polling, we must start the periodic fetch of data
|
|
125
|
-
if (storage.splits.
|
|
126
|
-
|
|
125
|
+
if (storage.splits.usesMatcher(IN_SEGMENT))
|
|
126
|
+
msSyncTask.start();
|
|
127
|
+
if (mlsSyncTask && storage.splits.usesMatcher(IN_LARGE_SEGMENT))
|
|
128
|
+
mlsSyncTask.start();
|
|
127
129
|
}
|
|
128
130
|
else {
|
|
129
131
|
// if not polling, we must execute the sync task for the initial fetch
|
|
130
132
|
// of segments since `syncAll` was already executed when starting the main client
|
|
131
|
-
|
|
133
|
+
msSyncTask.execute();
|
|
134
|
+
mlsSyncTask && mlsSyncTask.execute();
|
|
132
135
|
}
|
|
133
|
-
pushManager.add(matchingKey,
|
|
136
|
+
pushManager.add(matchingKey, msSyncTask, mlsSyncTask);
|
|
134
137
|
}
|
|
135
138
|
else {
|
|
136
|
-
if (storage.splits.
|
|
137
|
-
|
|
139
|
+
if (storage.splits.usesMatcher(IN_SEGMENT))
|
|
140
|
+
msSyncTask.start();
|
|
141
|
+
if (mlsSyncTask && storage.splits.usesMatcher(IN_LARGE_SEGMENT))
|
|
142
|
+
mlsSyncTask.start();
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
else {
|
|
141
|
-
if (!readinessManager.isReady())
|
|
142
|
-
|
|
146
|
+
if (!readinessManager.isReady()) {
|
|
147
|
+
msSyncTask.execute();
|
|
148
|
+
mlsSyncTask && mlsSyncTask.execute();
|
|
149
|
+
}
|
|
143
150
|
}
|
|
144
151
|
},
|
|
145
152
|
stop: function () {
|
|
146
153
|
// check in case `client.destroy()` has been invoked more than once for the same client
|
|
147
|
-
var
|
|
148
|
-
if (
|
|
154
|
+
var syncTasks = pollingManager.get(matchingKey);
|
|
155
|
+
if (syncTasks) {
|
|
156
|
+
var msSyncTask_1 = syncTasks.msSyncTask, mlsSyncTask_1 = syncTasks.mlsSyncTask;
|
|
149
157
|
// stop syncing
|
|
150
158
|
if (pushManager)
|
|
151
159
|
pushManager.remove(matchingKey);
|
|
152
|
-
if (
|
|
153
|
-
|
|
160
|
+
if (msSyncTask_1.isRunning())
|
|
161
|
+
msSyncTask_1.stop();
|
|
162
|
+
if (mlsSyncTask_1 && mlsSyncTask_1.isRunning())
|
|
163
|
+
mlsSyncTask_1.stop();
|
|
154
164
|
pollingManager.remove(matchingKey);
|
|
155
165
|
}
|
|
156
166
|
},
|
|
@@ -61,6 +61,7 @@ export var TELEMETRY = 'te';
|
|
|
61
61
|
export var TOKEN = 'to';
|
|
62
62
|
export var SEGMENT = 'se';
|
|
63
63
|
export var MY_SEGMENT = 'ms';
|
|
64
|
+
export var MY_LARGE_SEGMENT = 'mls';
|
|
64
65
|
export var TREATMENT = 't';
|
|
65
66
|
export var TREATMENTS = 'ts';
|
|
66
67
|
export var TREATMENT_WITH_CONFIG = 'tc';
|
|
@@ -87,3 +88,6 @@ export var DISABLED = 0;
|
|
|
87
88
|
export var ENABLED = 1;
|
|
88
89
|
export var PAUSED = 2;
|
|
89
90
|
export var FLAG_SPEC_VERSION = '1.1';
|
|
91
|
+
// Matcher types
|
|
92
|
+
export var IN_SEGMENT = 'IN_SEGMENT';
|
|
93
|
+
export var IN_LARGE_SEGMENT = 'IN_LARGE_SEGMENT';
|
|
@@ -5,7 +5,7 @@ import { STANDALONE_MODE, OPTIMIZED, LOCALHOST_MODE, DEBUG, FLAG_SPEC_VERSION }
|
|
|
5
5
|
import { validImpressionsMode } from './impressionsMode';
|
|
6
6
|
import { validateKey } from '../inputValidation/key';
|
|
7
7
|
import { validateTrafficType } from '../inputValidation/trafficType';
|
|
8
|
-
import { ERROR_MIN_CONFIG_PARAM } from '../../logger/constants';
|
|
8
|
+
import { ERROR_MIN_CONFIG_PARAM, LOG_PREFIX_CLIENT_INSTANTIATION } from '../../logger/constants';
|
|
9
9
|
// Exported for telemetry
|
|
10
10
|
export var base = {
|
|
11
11
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
@@ -27,6 +27,8 @@ export var base = {
|
|
|
27
27
|
featuresRefreshRate: 60,
|
|
28
28
|
// fetch segments updates each 60 sec
|
|
29
29
|
segmentsRefreshRate: 60,
|
|
30
|
+
// fetch large segments updates each 60 sec
|
|
31
|
+
largeSegmentsRefreshRate: 60,
|
|
30
32
|
// publish telemetry stats each 3600 secs (1 hour)
|
|
31
33
|
telemetryRefreshRate: 3600,
|
|
32
34
|
// publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
|
|
@@ -72,7 +74,8 @@ export var base = {
|
|
|
72
74
|
impressionsMode: OPTIMIZED,
|
|
73
75
|
localhostMode: undefined,
|
|
74
76
|
enabled: true,
|
|
75
|
-
flagSpecVersion: FLAG_SPEC_VERSION
|
|
77
|
+
flagSpecVersion: FLAG_SPEC_VERSION,
|
|
78
|
+
largeSegmentsEnabled: false
|
|
76
79
|
},
|
|
77
80
|
// Logger
|
|
78
81
|
log: undefined
|
|
@@ -111,6 +114,7 @@ export function settingsValidation(config, validationParams) {
|
|
|
111
114
|
var scheduler = withDefaults.scheduler, startup = withDefaults.startup;
|
|
112
115
|
scheduler.featuresRefreshRate = fromSecondsToMillis(scheduler.featuresRefreshRate);
|
|
113
116
|
scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
|
|
117
|
+
scheduler.largeSegmentsRefreshRate = fromSecondsToMillis(scheduler.largeSegmentsRefreshRate);
|
|
114
118
|
scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
|
|
115
119
|
scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
|
|
116
120
|
scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
|
|
@@ -143,12 +147,12 @@ export function settingsValidation(config, validationParams) {
|
|
|
143
147
|
// Keeping same behaviour than JS SDK: if settings key or TT are invalid,
|
|
144
148
|
// `false` value is used as bound key/TT of the default client, which leads to some issues.
|
|
145
149
|
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
|
|
146
|
-
withDefaults.core.key = validateKey(log, maybeKey,
|
|
150
|
+
withDefaults.core.key = validateKey(log, maybeKey, LOG_PREFIX_CLIENT_INSTANTIATION);
|
|
147
151
|
}
|
|
148
152
|
if (validationParams.acceptTT) {
|
|
149
153
|
var maybeTT = withDefaults.core.trafficType;
|
|
150
154
|
if (maybeTT !== undefined) { // @ts-ignore
|
|
151
|
-
withDefaults.core.trafficType = validateTrafficType(log, maybeTT,
|
|
155
|
+
withDefaults.core.trafficType = validateTrafficType(log, maybeTT, LOG_PREFIX_CLIENT_INSTANTIATION);
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
158
|
}
|
|
@@ -183,9 +187,10 @@ export function settingsValidation(config, validationParams) {
|
|
|
183
187
|
var splitFiltersValidation = validateSplitFilters(log, sync.splitFilters, withDefaults.mode);
|
|
184
188
|
sync.splitFilters = splitFiltersValidation.validFilters;
|
|
185
189
|
sync.__splitFiltersValidation = splitFiltersValidation;
|
|
190
|
+
// ensure a valid flag spec version
|
|
186
191
|
sync.flagSpecVersion = flagSpec ? flagSpec(withDefaults) : FLAG_SPEC_VERSION;
|
|
187
192
|
// ensure a valid user consent value
|
|
188
193
|
// @ts-ignore, modify readonly prop
|
|
189
|
-
withDefaults.userConsent = consent(withDefaults);
|
|
194
|
+
withDefaults.userConsent = consent ? consent(withDefaults) : undefined;
|
|
190
195
|
return withDefaults;
|
|
191
196
|
}
|
package/package.json
CHANGED
package/src/dtos/types.ts
CHANGED
|
@@ -61,6 +61,11 @@ interface IInSegmentMatcher extends ISplitMatcherBase {
|
|
|
61
61
|
userDefinedSegmentMatcherData: IInSegmentMatcherData
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
interface IInLargeSegmentMatcher extends ISplitMatcherBase {
|
|
65
|
+
matcherType: 'IN_LARGE_SEGMENT',
|
|
66
|
+
userDefinedSegmentMatcherData: IInSegmentMatcherData
|
|
67
|
+
}
|
|
68
|
+
|
|
64
69
|
interface IWhitelistMatcher extends ISplitMatcherBase {
|
|
65
70
|
matcherType: 'WHITELIST',
|
|
66
71
|
whitelistMatcherData: IWhitelistMatcherData
|
|
@@ -165,7 +170,8 @@ interface IInListSemverMatcher extends ISplitMatcherBase {
|
|
|
165
170
|
export type ISplitMatcher = IAllKeysMatcher | IInSegmentMatcher | IWhitelistMatcher | IEqualToMatcher | IGreaterThanOrEqualToMatcher |
|
|
166
171
|
ILessThanOrEqualToMatcher | IBetweenMatcher | IEqualToSetMatcher | IContainsAnyOfSetMatcher | IContainsAllOfSetMatcher | IPartOfSetMatcher |
|
|
167
172
|
IStartsWithMatcher | IEndsWithMatcher | IContainsStringMatcher | IInSplitTreatmentMatcher | IEqualToBooleanMatcher | IMatchesStringMatcher |
|
|
168
|
-
IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher
|
|
173
|
+
IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher |
|
|
174
|
+
IInLargeSegmentMatcher
|
|
169
175
|
|
|
170
176
|
/** Split object */
|
|
171
177
|
export interface ISplitPartition {
|
|
@@ -218,14 +224,18 @@ export interface ISegmentChangesResponse {
|
|
|
218
224
|
till: number
|
|
219
225
|
}
|
|
220
226
|
|
|
221
|
-
export interface IMySegmentsResponseItem {
|
|
222
|
-
id: string,
|
|
223
|
-
name: string
|
|
224
|
-
}
|
|
225
|
-
|
|
226
227
|
/** Interface of the parsed JSON response of `/mySegments/{userKey}` */
|
|
227
228
|
export interface IMySegmentsResponse {
|
|
228
|
-
mySegments:
|
|
229
|
+
mySegments: {
|
|
230
|
+
id: string,
|
|
231
|
+
name: string
|
|
232
|
+
}[]
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/** Interface of the parsed JSON response of `/myLargeSegments/{userKey}` */
|
|
236
|
+
export interface IMyLargeSegmentsResponse {
|
|
237
|
+
myLargeSegments: string[],
|
|
238
|
+
changeNumber: number
|
|
229
239
|
}
|
|
230
240
|
|
|
231
241
|
/** Metadata internal type for storages */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { allMatcherContext } from './all';
|
|
2
2
|
import { segmentMatcherContext } from './segment';
|
|
3
|
+
import { largeSegmentMatcherContext } from './large_segment';
|
|
3
4
|
import { whitelistMatcherContext } from './whitelist';
|
|
4
5
|
import { equalToMatcherContext } from './eq';
|
|
5
6
|
import { greaterThanEqualMatcherContext } from './gte';
|
|
@@ -48,6 +49,7 @@ const matchers = [
|
|
|
48
49
|
lessThanEqualToSemverMatcherContext, // LESS_THAN_OR_EQUAL_TO_SEMVER: 20
|
|
49
50
|
betweenSemverMatcherContext, // BETWEEN_SEMVER: 21
|
|
50
51
|
inListSemverMatcherContext, // IN_LIST_SEMVER: 22
|
|
52
|
+
largeSegmentMatcherContext, // IN_LARGE_SEGMENT: 23
|
|
51
53
|
];
|
|
52
54
|
|
|
53
55
|
/**
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { MaybeThenable } from '../../dtos/types';
|
|
2
|
+
import { ISegmentsCacheBase } from '../../storages/types';
|
|
3
|
+
import { thenable } from '../../utils/promise/thenable';
|
|
4
|
+
|
|
5
|
+
export function largeSegmentMatcherContext(largeSegmentName: string, storage: { largeSegments?: ISegmentsCacheBase }) {
|
|
6
|
+
|
|
7
|
+
return function largeSegmentMatcher(key: string): MaybeThenable<boolean> {
|
|
8
|
+
const isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false;
|
|
9
|
+
|
|
10
|
+
if (thenable(isInLargeSegment)) {
|
|
11
|
+
isInLargeSegment.then(result => {
|
|
12
|
+
return result;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return isInLargeSegment;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -33,7 +33,7 @@ export function matchersTransform(matchers: ISplitMatcher[]): IMatcherDto[] {
|
|
|
33
33
|
let dataType = matcherDataTypes.STRING;
|
|
34
34
|
let value = undefined;
|
|
35
35
|
|
|
36
|
-
if (type === matcherTypes.IN_SEGMENT) {
|
|
36
|
+
if (type === matcherTypes.IN_SEGMENT || type === matcherTypes.IN_LARGE_SEGMENT) {
|
|
37
37
|
value = segmentTransform(userDefinedSegmentMatcherData as IInSegmentMatcherData);
|
|
38
38
|
} else if (type === matcherTypes.EQUAL_TO) {
|
|
39
39
|
value = numericTransform(unaryNumericMatcherData as IUnaryNumericMatcherData);
|
package/src/logger/constants.ts
CHANGED
|
@@ -36,7 +36,6 @@ export const IMPRESSION = 102;
|
|
|
36
36
|
export const IMPRESSION_QUEUEING = 103;
|
|
37
37
|
export const NEW_SHARED_CLIENT = 104;
|
|
38
38
|
export const NEW_FACTORY = 105;
|
|
39
|
-
export const POLLING_SMART_PAUSING = 106;
|
|
40
39
|
export const POLLING_START = 107;
|
|
41
40
|
export const POLLING_STOP = 108;
|
|
42
41
|
export const SYNC_SPLITS_FETCH_RETRY = 109;
|
|
@@ -120,6 +119,7 @@ export const ENGINE_MATCHER_ERROR = 329;
|
|
|
120
119
|
// Log prefixes (a.k.a. tags or categories)
|
|
121
120
|
export const LOG_PREFIX_SETTINGS = 'settings';
|
|
122
121
|
export const LOG_PREFIX_INSTANTIATION = 'Factory instantiation';
|
|
122
|
+
export const LOG_PREFIX_CLIENT_INSTANTIATION = 'Client instantiation';
|
|
123
123
|
export const LOG_PREFIX_ENGINE = 'engine';
|
|
124
124
|
export const LOG_PREFIX_ENGINE_COMBINER = LOG_PREFIX_ENGINE + ':combiner: ';
|
|
125
125
|
export const LOG_PREFIX_ENGINE_MATCHER = LOG_PREFIX_ENGINE + ':matcher: ';
|
|
@@ -19,7 +19,6 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
19
19
|
[c.USER_CONSENT_INITIAL, 'Starting the SDK with %s user consent. No data will be sent.'],
|
|
20
20
|
|
|
21
21
|
// synchronizer
|
|
22
|
-
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
23
22
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
24
23
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
25
24
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
|
-
import { IEventEmitter } from '../types';
|
|
2
|
+
import { IEventEmitter, ISettings } from '../types';
|
|
3
3
|
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
|
|
4
4
|
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
|
|
5
5
|
|
|
@@ -18,10 +18,8 @@ function splitsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISpli
|
|
|
18
18
|
return splitsEventEmitter;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
function segmentsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISegmentsEventEmitter {
|
|
22
|
-
const segmentsEventEmitter = objectAssign(new EventEmitter(), {
|
|
23
|
-
segmentsArrived: false
|
|
24
|
-
});
|
|
21
|
+
function segmentsEventEmitterFactory(EventEmitter: new () => IEventEmitter, segmentsArrived = false): ISegmentsEventEmitter {
|
|
22
|
+
const segmentsEventEmitter = objectAssign(new EventEmitter(), { segmentsArrived });
|
|
25
23
|
|
|
26
24
|
segmentsEventEmitter.once(SDK_SEGMENTS_ARRIVED, () => { segmentsEventEmitter.segmentsArrived = true; });
|
|
27
25
|
|
|
@@ -33,10 +31,13 @@ function segmentsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISe
|
|
|
33
31
|
*/
|
|
34
32
|
export function readinessManagerFactory(
|
|
35
33
|
EventEmitter: new () => IEventEmitter,
|
|
36
|
-
|
|
34
|
+
settings: ISettings,
|
|
37
35
|
splits: ISplitsEventEmitter = splitsEventEmitterFactory(EventEmitter)): IReadinessManager {
|
|
38
36
|
|
|
37
|
+
const { startup: { readyTimeout, waitForLargeSegments }, sync: { largeSegmentsEnabled } } = settings;
|
|
38
|
+
|
|
39
39
|
const segments: ISegmentsEventEmitter = segmentsEventEmitterFactory(EventEmitter);
|
|
40
|
+
const largeSegments = largeSegmentsEnabled ? segmentsEventEmitterFactory(EventEmitter, !waitForLargeSegments) : undefined;
|
|
40
41
|
const gate: IReadinessEventEmitter = new EventEmitter();
|
|
41
42
|
|
|
42
43
|
// emit SDK_READY_FROM_CACHE
|
|
@@ -62,6 +63,7 @@ export function readinessManagerFactory(
|
|
|
62
63
|
let isReady = false;
|
|
63
64
|
splits.on(SDK_SPLITS_ARRIVED, checkIsReadyOrUpdate);
|
|
64
65
|
segments.on(SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
|
|
66
|
+
if (largeSegments) largeSegments.on(SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
|
|
65
67
|
|
|
66
68
|
let isDestroyed = false;
|
|
67
69
|
|
|
@@ -87,7 +89,7 @@ export function readinessManagerFactory(
|
|
|
87
89
|
setTimeout(() => { throw e; }, 0);
|
|
88
90
|
}
|
|
89
91
|
} else {
|
|
90
|
-
if (splits.splitsArrived && segments.segmentsArrived) {
|
|
92
|
+
if (splits.splitsArrived && segments.segmentsArrived && (!largeSegments || largeSegments.segmentsArrived)) {
|
|
91
93
|
clearTimeout(readyTimeoutId);
|
|
92
94
|
isReady = true;
|
|
93
95
|
try {
|
|
@@ -105,11 +107,12 @@ export function readinessManagerFactory(
|
|
|
105
107
|
return {
|
|
106
108
|
splits,
|
|
107
109
|
segments,
|
|
110
|
+
largeSegments,
|
|
108
111
|
gate,
|
|
109
112
|
|
|
110
|
-
shared(
|
|
113
|
+
shared() {
|
|
111
114
|
refCount++;
|
|
112
|
-
return readinessManagerFactory(EventEmitter,
|
|
115
|
+
return readinessManagerFactory(EventEmitter, settings, splits);
|
|
113
116
|
},
|
|
114
117
|
|
|
115
118
|
// @TODO review/remove next methods when non-recoverable errors are reworked
|
|
@@ -123,6 +126,7 @@ export function readinessManagerFactory(
|
|
|
123
126
|
isDestroyed = true;
|
|
124
127
|
|
|
125
128
|
segments.removeAllListeners();
|
|
129
|
+
if (largeSegments) largeSegments.removeAllListeners();
|
|
126
130
|
gate.removeAllListeners();
|
|
127
131
|
clearTimeout(readyTimeoutId);
|
|
128
132
|
|
|
@@ -2,9 +2,8 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
2
2
|
import { promiseWrapper } from '../utils/promise/wrapper';
|
|
3
3
|
import { readinessManagerFactory } from './readinessManager';
|
|
4
4
|
import { ISdkReadinessManager } from './types';
|
|
5
|
-
import { IEventEmitter } from '../types';
|
|
5
|
+
import { IEventEmitter, ISettings } from '../types';
|
|
6
6
|
import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants';
|
|
7
|
-
import { ILogger } from '../logger/types';
|
|
8
7
|
import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY, CLIENT_NO_LISTENER } from '../logger/constants';
|
|
9
8
|
|
|
10
9
|
const NEW_LISTENER_EVENT = 'newListener';
|
|
@@ -18,10 +17,11 @@ const REMOVE_LISTENER_EVENT = 'removeListener';
|
|
|
18
17
|
* @param readinessManager optional readinessManager to use. only used internally for `shared` method
|
|
19
18
|
*/
|
|
20
19
|
export function sdkReadinessManagerFactory(
|
|
21
|
-
log: ILogger,
|
|
22
20
|
EventEmitter: new () => IEventEmitter,
|
|
23
|
-
|
|
24
|
-
readinessManager = readinessManagerFactory(EventEmitter,
|
|
21
|
+
settings: ISettings,
|
|
22
|
+
readinessManager = readinessManagerFactory(EventEmitter, settings)): ISdkReadinessManager {
|
|
23
|
+
|
|
24
|
+
const log = settings.log;
|
|
25
25
|
|
|
26
26
|
/** Ready callback warning */
|
|
27
27
|
let internalReadyCbCount = 0;
|
|
@@ -72,8 +72,8 @@ export function sdkReadinessManagerFactory(
|
|
|
72
72
|
return {
|
|
73
73
|
readinessManager,
|
|
74
74
|
|
|
75
|
-
shared(
|
|
76
|
-
return sdkReadinessManagerFactory(
|
|
75
|
+
shared() {
|
|
76
|
+
return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
|
|
77
77
|
},
|
|
78
78
|
|
|
79
79
|
incInternalReadyCbCount() {
|