@splitsoftware/splitio-commons 2.10.1 → 2.10.2-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +5 -1
- package/cjs/readiness/readinessManager.js +19 -6
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +2 -2
- package/cjs/sync/polling/pollingManagerCS.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +5 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +10 -3
- package/cjs/sync/submitters/submitterManager.js +1 -1
- package/esm/readiness/readinessManager.js +19 -6
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +2 -2
- package/esm/sync/polling/pollingManagerCS.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +5 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +10 -3
- package/esm/sync/submitters/submitterManager.js +1 -1
- package/package.json +1 -1
- package/src/readiness/readinessManager.ts +19 -6
- package/src/readiness/types.ts +27 -13
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +3 -2
- package/src/sync/polling/pollingManagerCS.ts +3 -2
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -1
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +8 -2
- package/src/sync/polling/updaters/splitChangesUpdater.ts +13 -4
- package/src/sync/submitters/submitterManager.ts +1 -1
- package/src/sync/submitters/types.ts +1 -1
- package/src/sync/types.ts +1 -1
- package/types/splitio.d.ts +55 -0
package/CHANGES.txt
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
2.11.0 (January XX, 2026)
|
|
2
|
+
- Added metadata to SDK_UPDATE events to indicate the type of update (FLAGS_UPDATE or SEGMENTS_UPDATE) and the names of updated flags or segments.
|
|
3
|
+
- Added metadata to SDK_READY and SDK_READY_FROM_CACHE events, including `initialCacheLoad` (boolean indicating if SDK was loaded from cache) and `lastUpdateTimestamp` (Int64 milliseconds since epoch).
|
|
4
|
+
|
|
1
5
|
2.10.1 (December 18, 2025)
|
|
2
|
-
- Bugfix - Handle `null` prerequisites properly
|
|
6
|
+
- Bugfix - Handle `null` prerequisites properly.
|
|
3
7
|
|
|
4
8
|
2.10.0 (December 16, 2025)
|
|
5
9
|
- Added property `impressionsDisabled` in getTreatment(s) `evaluationOptions` parameter, to disable impressions per evaluations.
|
|
@@ -13,7 +13,7 @@ function splitsEventEmitterFactory(EventEmitter) {
|
|
|
13
13
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
14
14
|
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
15
15
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
16
|
-
splitsEventEmitter.on(constants_1.SDK_SPLITS_ARRIVED, function (isSplitKill) { if (!isSplitKill)
|
|
16
|
+
splitsEventEmitter.on(constants_1.SDK_SPLITS_ARRIVED, function (metadata, isSplitKill) { if (!isSplitKill)
|
|
17
17
|
splitsEventEmitter.splitsArrived = true; });
|
|
18
18
|
splitsEventEmitter.once(constants_1.SDK_SPLITS_CACHE_LOADED, function () { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
19
19
|
return splitsEventEmitter;
|
|
@@ -74,7 +74,11 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
74
74
|
if (!isReady && !isDestroyed) {
|
|
75
75
|
try {
|
|
76
76
|
syncLastUpdate();
|
|
77
|
-
|
|
77
|
+
var metadata = {
|
|
78
|
+
initialCacheLoad: true,
|
|
79
|
+
lastUpdateTimestamp: lastUpdate
|
|
80
|
+
};
|
|
81
|
+
gate.emit(constants_1.SDK_READY_FROM_CACHE, metadata);
|
|
78
82
|
}
|
|
79
83
|
catch (e) {
|
|
80
84
|
// throws user callback exceptions in next tick
|
|
@@ -82,13 +86,13 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
|
-
function checkIsReadyOrUpdate(
|
|
89
|
+
function checkIsReadyOrUpdate(metadata) {
|
|
86
90
|
if (isDestroyed)
|
|
87
91
|
return;
|
|
88
92
|
if (isReady) {
|
|
89
93
|
try {
|
|
90
94
|
syncLastUpdate();
|
|
91
|
-
gate.emit(constants_1.SDK_UPDATE,
|
|
95
|
+
gate.emit(constants_1.SDK_UPDATE, metadata);
|
|
92
96
|
}
|
|
93
97
|
catch (e) {
|
|
94
98
|
// throws user callback exceptions in next tick
|
|
@@ -101,11 +105,20 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
101
105
|
isReady = true;
|
|
102
106
|
try {
|
|
103
107
|
syncLastUpdate();
|
|
108
|
+
var wasReadyFromCache = isReadyFromCache;
|
|
104
109
|
if (!isReadyFromCache) {
|
|
105
110
|
isReadyFromCache = true;
|
|
106
|
-
|
|
111
|
+
var metadataFromCache = {
|
|
112
|
+
initialCacheLoad: false,
|
|
113
|
+
lastUpdateTimestamp: lastUpdate
|
|
114
|
+
};
|
|
115
|
+
gate.emit(constants_1.SDK_READY_FROM_CACHE, metadataFromCache);
|
|
107
116
|
}
|
|
108
|
-
|
|
117
|
+
var metadataReady = {
|
|
118
|
+
initialCacheLoad: wasReadyFromCache,
|
|
119
|
+
lastUpdateTimestamp: lastUpdate
|
|
120
|
+
};
|
|
121
|
+
gate.emit(constants_1.SDK_READY, metadataReady);
|
|
109
122
|
}
|
|
110
123
|
catch (e) {
|
|
111
124
|
// throws user callback exceptions in next tick
|
|
@@ -42,7 +42,7 @@ function fromObjectUpdaterFactory(splitsParser, storage, readiness, settings) {
|
|
|
42
42
|
splitsCache.clear(),
|
|
43
43
|
splitsCache.update(splits, [], Date.now())
|
|
44
44
|
]).then(function () {
|
|
45
|
-
readiness.splits.emit(constants_2.SDK_SPLITS_ARRIVED);
|
|
45
|
+
readiness.splits.emit(constants_2.SDK_SPLITS_ARRIVED, { type: "FLAGS_UPDATE" /* FLAGS_UPDATE */, names: [] });
|
|
46
46
|
if (startingUp) {
|
|
47
47
|
startingUp = false;
|
|
48
48
|
Promise.resolve(storage.validateCache ? storage.validateCache() : false).then(function (isCacheLoaded) {
|
|
@@ -50,7 +50,7 @@ function fromObjectUpdaterFactory(splitsParser, storage, readiness, settings) {
|
|
|
50
50
|
if (isCacheLoaded)
|
|
51
51
|
readiness.splits.emit(constants_2.SDK_SPLITS_CACHE_LOADED);
|
|
52
52
|
// Emits SDK_READY
|
|
53
|
-
readiness.segments.emit(constants_2.SDK_SEGMENTS_ARRIVED);
|
|
53
|
+
readiness.segments.emit(constants_2.SDK_SEGMENTS_ARRIVED, { type: "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */, names: [] });
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
return true;
|
|
@@ -49,9 +49,9 @@ function pollingManagerCSFactory(params) {
|
|
|
49
49
|
function add(matchingKey, readiness, storage) {
|
|
50
50
|
var mySegmentsSyncTask = (0, mySegmentsSyncTask_1.mySegmentsSyncTaskFactory)(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
51
51
|
// smart ready
|
|
52
|
-
function smartReady() {
|
|
52
|
+
function smartReady(metadata) {
|
|
53
53
|
if (!readiness.isReady() && !(0, AbstractSplitsCacheSync_1.usesSegmentsSync)(storage))
|
|
54
|
-
readiness.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED);
|
|
54
|
+
readiness.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED, metadata);
|
|
55
55
|
}
|
|
56
56
|
if (!(0, AbstractSplitsCacheSync_1.usesSegmentsSync)(storage))
|
|
57
57
|
setTimeout(smartReady, 0);
|
|
@@ -39,7 +39,7 @@ function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmentsEvent
|
|
|
39
39
|
// Notify update if required
|
|
40
40
|
if ((0, AbstractSplitsCacheSync_1.usesSegmentsSync)(storage) && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
41
41
|
readyOnAlreadyExistentState = false;
|
|
42
|
-
segmentsEventEmitter.emit(constants_1.SDK_SEGMENTS_ARRIVED);
|
|
42
|
+
segmentsEventEmitter.emit(constants_1.SDK_SEGMENTS_ARRIVED, { type: "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */, names: [] });
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
function _mySegmentsUpdater(retry, segmentsData, noCache, till) {
|
|
@@ -66,8 +66,12 @@ function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, read
|
|
|
66
66
|
// if at least one segment fetch succeeded, mark segments ready
|
|
67
67
|
if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) {
|
|
68
68
|
readyOnAlreadyExistentState = false;
|
|
69
|
+
var metadata = {
|
|
70
|
+
type: "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */,
|
|
71
|
+
names: []
|
|
72
|
+
};
|
|
69
73
|
if (readiness)
|
|
70
|
-
readiness.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED);
|
|
74
|
+
readiness.segments.emit(constants_1.SDK_SEGMENTS_ARRIVED, metadata);
|
|
71
75
|
}
|
|
72
76
|
return true;
|
|
73
77
|
});
|
|
@@ -79,8 +79,9 @@ function computeMutation(rules, segments, filters) {
|
|
|
79
79
|
else {
|
|
80
80
|
accum.removed.push(ruleEntity);
|
|
81
81
|
}
|
|
82
|
+
accum.names.push(ruleEntity.name);
|
|
82
83
|
return accum;
|
|
83
|
-
}, { added: [], removed: [] });
|
|
84
|
+
}, { added: [], removed: [], names: [] });
|
|
84
85
|
}
|
|
85
86
|
exports.computeMutation = computeMutation;
|
|
86
87
|
/**
|
|
@@ -136,9 +137,11 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFilt
|
|
|
136
137
|
splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
|
|
137
138
|
.then(function (splitChanges) {
|
|
138
139
|
var usedSegments = new Set();
|
|
140
|
+
var updatedFlags = [];
|
|
139
141
|
var ffUpdate = false;
|
|
140
142
|
if (splitChanges.ff) {
|
|
141
|
-
var _a = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed;
|
|
143
|
+
var _a = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
|
|
144
|
+
updatedFlags = names;
|
|
142
145
|
log.debug(constants_2.SYNC_SPLITS_UPDATE, [added.length, removed.length]);
|
|
143
146
|
ffUpdate = splits.update(added, removed, splitChanges.ff.t);
|
|
144
147
|
}
|
|
@@ -161,9 +164,13 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFilt
|
|
|
161
164
|
return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
162
165
|
.catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
163
166
|
.then(function (emitSplitsArrivedEvent) {
|
|
167
|
+
var metadata = {
|
|
168
|
+
type: updatedFlags.length > 0 ? "FLAGS_UPDATE" /* FLAGS_UPDATE */ : "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */,
|
|
169
|
+
names: updatedFlags.length > 0 ? updatedFlags : []
|
|
170
|
+
};
|
|
164
171
|
// emit SDK events
|
|
165
172
|
if (emitSplitsArrivedEvent)
|
|
166
|
-
splitsEventEmitter.emit(constants_1.SDK_SPLITS_ARRIVED);
|
|
173
|
+
splitsEventEmitter.emit(constants_1.SDK_SPLITS_ARRIVED, metadata);
|
|
167
174
|
return true;
|
|
168
175
|
});
|
|
169
176
|
}
|
|
@@ -36,7 +36,7 @@ function submitterManagerFactory(params) {
|
|
|
36
36
|
var promises = onlyTelemetry ? [] : submitters.map(function (submitter) { return submitter.execute(); });
|
|
37
37
|
if (telemetrySubmitter)
|
|
38
38
|
promises.push(telemetrySubmitter.execute());
|
|
39
|
-
return Promise.all(promises);
|
|
39
|
+
return Promise.all(promises).then(function () { });
|
|
40
40
|
},
|
|
41
41
|
isExecuting: function () {
|
|
42
42
|
return submitters.some(function (submitter) { return submitter.isExecuting(); });
|
|
@@ -10,7 +10,7 @@ function splitsEventEmitterFactory(EventEmitter) {
|
|
|
10
10
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
11
11
|
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
12
12
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
13
|
-
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, function (isSplitKill) { if (!isSplitKill)
|
|
13
|
+
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, function (metadata, isSplitKill) { if (!isSplitKill)
|
|
14
14
|
splitsEventEmitter.splitsArrived = true; });
|
|
15
15
|
splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, function () { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
16
16
|
return splitsEventEmitter;
|
|
@@ -71,7 +71,11 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
|
|
|
71
71
|
if (!isReady && !isDestroyed) {
|
|
72
72
|
try {
|
|
73
73
|
syncLastUpdate();
|
|
74
|
-
|
|
74
|
+
var metadata = {
|
|
75
|
+
initialCacheLoad: true,
|
|
76
|
+
lastUpdateTimestamp: lastUpdate
|
|
77
|
+
};
|
|
78
|
+
gate.emit(SDK_READY_FROM_CACHE, metadata);
|
|
75
79
|
}
|
|
76
80
|
catch (e) {
|
|
77
81
|
// throws user callback exceptions in next tick
|
|
@@ -79,13 +83,13 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
|
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
85
|
}
|
|
82
|
-
function checkIsReadyOrUpdate(
|
|
86
|
+
function checkIsReadyOrUpdate(metadata) {
|
|
83
87
|
if (isDestroyed)
|
|
84
88
|
return;
|
|
85
89
|
if (isReady) {
|
|
86
90
|
try {
|
|
87
91
|
syncLastUpdate();
|
|
88
|
-
gate.emit(SDK_UPDATE,
|
|
92
|
+
gate.emit(SDK_UPDATE, metadata);
|
|
89
93
|
}
|
|
90
94
|
catch (e) {
|
|
91
95
|
// throws user callback exceptions in next tick
|
|
@@ -98,11 +102,20 @@ export function readinessManagerFactory(EventEmitter, settings, splits, isShared
|
|
|
98
102
|
isReady = true;
|
|
99
103
|
try {
|
|
100
104
|
syncLastUpdate();
|
|
105
|
+
var wasReadyFromCache = isReadyFromCache;
|
|
101
106
|
if (!isReadyFromCache) {
|
|
102
107
|
isReadyFromCache = true;
|
|
103
|
-
|
|
108
|
+
var metadataFromCache = {
|
|
109
|
+
initialCacheLoad: false,
|
|
110
|
+
lastUpdateTimestamp: lastUpdate
|
|
111
|
+
};
|
|
112
|
+
gate.emit(SDK_READY_FROM_CACHE, metadataFromCache);
|
|
104
113
|
}
|
|
105
|
-
|
|
114
|
+
var metadataReady = {
|
|
115
|
+
initialCacheLoad: wasReadyFromCache,
|
|
116
|
+
lastUpdateTimestamp: lastUpdate
|
|
117
|
+
};
|
|
118
|
+
gate.emit(SDK_READY, metadataReady);
|
|
106
119
|
}
|
|
107
120
|
catch (e) {
|
|
108
121
|
// throws user callback exceptions in next tick
|
|
@@ -39,7 +39,7 @@ export function fromObjectUpdaterFactory(splitsParser, storage, readiness, setti
|
|
|
39
39
|
splitsCache.clear(),
|
|
40
40
|
splitsCache.update(splits, [], Date.now())
|
|
41
41
|
]).then(function () {
|
|
42
|
-
readiness.splits.emit(SDK_SPLITS_ARRIVED);
|
|
42
|
+
readiness.splits.emit(SDK_SPLITS_ARRIVED, { type: "FLAGS_UPDATE" /* FLAGS_UPDATE */, names: [] });
|
|
43
43
|
if (startingUp) {
|
|
44
44
|
startingUp = false;
|
|
45
45
|
Promise.resolve(storage.validateCache ? storage.validateCache() : false).then(function (isCacheLoaded) {
|
|
@@ -47,7 +47,7 @@ export function fromObjectUpdaterFactory(splitsParser, storage, readiness, setti
|
|
|
47
47
|
if (isCacheLoaded)
|
|
48
48
|
readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
|
|
49
49
|
// Emits SDK_READY
|
|
50
|
-
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
50
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, { type: "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */, names: [] });
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
return true;
|
|
@@ -46,9 +46,9 @@ export function pollingManagerCSFactory(params) {
|
|
|
46
46
|
function add(matchingKey, readiness, storage) {
|
|
47
47
|
var mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
48
48
|
// smart ready
|
|
49
|
-
function smartReady() {
|
|
49
|
+
function smartReady(metadata) {
|
|
50
50
|
if (!readiness.isReady() && !usesSegmentsSync(storage))
|
|
51
|
-
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
51
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
52
52
|
}
|
|
53
53
|
if (!usesSegmentsSync(storage))
|
|
54
54
|
setTimeout(smartReady, 0);
|
|
@@ -36,7 +36,7 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmen
|
|
|
36
36
|
// Notify update if required
|
|
37
37
|
if (usesSegmentsSync(storage) && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
38
38
|
readyOnAlreadyExistentState = false;
|
|
39
|
-
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED);
|
|
39
|
+
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED, { type: "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */, names: [] });
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
function _mySegmentsUpdater(retry, segmentsData, noCache, till) {
|
|
@@ -63,8 +63,12 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
63
63
|
// if at least one segment fetch succeeded, mark segments ready
|
|
64
64
|
if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) {
|
|
65
65
|
readyOnAlreadyExistentState = false;
|
|
66
|
+
var metadata = {
|
|
67
|
+
type: "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */,
|
|
68
|
+
names: []
|
|
69
|
+
};
|
|
66
70
|
if (readiness)
|
|
67
|
-
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
71
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
68
72
|
}
|
|
69
73
|
return true;
|
|
70
74
|
});
|
|
@@ -75,8 +75,9 @@ export function computeMutation(rules, segments, filters) {
|
|
|
75
75
|
else {
|
|
76
76
|
accum.removed.push(ruleEntity);
|
|
77
77
|
}
|
|
78
|
+
accum.names.push(ruleEntity.name);
|
|
78
79
|
return accum;
|
|
79
|
-
}, { added: [], removed: [] });
|
|
80
|
+
}, { added: [], removed: [], names: [] });
|
|
80
81
|
}
|
|
81
82
|
/**
|
|
82
83
|
* factory of SplitChanges updater, a task that:
|
|
@@ -131,9 +132,11 @@ export function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, sp
|
|
|
131
132
|
splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
|
|
132
133
|
.then(function (splitChanges) {
|
|
133
134
|
var usedSegments = new Set();
|
|
135
|
+
var updatedFlags = [];
|
|
134
136
|
var ffUpdate = false;
|
|
135
137
|
if (splitChanges.ff) {
|
|
136
|
-
var _a = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed;
|
|
138
|
+
var _a = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
|
|
139
|
+
updatedFlags = names;
|
|
137
140
|
log.debug(SYNC_SPLITS_UPDATE, [added.length, removed.length]);
|
|
138
141
|
ffUpdate = splits.update(added, removed, splitChanges.ff.t);
|
|
139
142
|
}
|
|
@@ -156,9 +159,13 @@ export function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, sp
|
|
|
156
159
|
return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
157
160
|
.catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
158
161
|
.then(function (emitSplitsArrivedEvent) {
|
|
162
|
+
var metadata = {
|
|
163
|
+
type: updatedFlags.length > 0 ? "FLAGS_UPDATE" /* FLAGS_UPDATE */ : "SEGMENTS_UPDATE" /* SEGMENTS_UPDATE */,
|
|
164
|
+
names: updatedFlags.length > 0 ? updatedFlags : []
|
|
165
|
+
};
|
|
159
166
|
// emit SDK events
|
|
160
167
|
if (emitSplitsArrivedEvent)
|
|
161
|
-
splitsEventEmitter.emit(SDK_SPLITS_ARRIVED);
|
|
168
|
+
splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, metadata);
|
|
162
169
|
return true;
|
|
163
170
|
});
|
|
164
171
|
}
|
|
@@ -33,7 +33,7 @@ export function submitterManagerFactory(params) {
|
|
|
33
33
|
var promises = onlyTelemetry ? [] : submitters.map(function (submitter) { return submitter.execute(); });
|
|
34
34
|
if (telemetrySubmitter)
|
|
35
35
|
promises.push(telemetrySubmitter.execute());
|
|
36
|
-
return Promise.all(promises);
|
|
36
|
+
return Promise.all(promises).then(function () { });
|
|
37
37
|
},
|
|
38
38
|
isExecuting: function () {
|
|
39
39
|
return submitters.some(function (submitter) { return submitter.isExecuting(); });
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@ function splitsEventEmitterFactory(EventEmitter: new () => SplitIO.IEventEmitter
|
|
|
15
15
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
16
16
|
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
17
17
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
18
|
-
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
|
|
18
|
+
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (metadata: SplitIO.SdkUpdateMetadata, isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
|
|
19
19
|
splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, () => { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
20
20
|
|
|
21
21
|
return splitsEventEmitter;
|
|
@@ -90,7 +90,11 @@ export function readinessManagerFactory(
|
|
|
90
90
|
if (!isReady && !isDestroyed) {
|
|
91
91
|
try {
|
|
92
92
|
syncLastUpdate();
|
|
93
|
-
|
|
93
|
+
const metadata: SplitIO.SdkReadyMetadata = {
|
|
94
|
+
initialCacheLoad: true,
|
|
95
|
+
lastUpdateTimestamp: lastUpdate
|
|
96
|
+
};
|
|
97
|
+
gate.emit(SDK_READY_FROM_CACHE, metadata);
|
|
94
98
|
} catch (e) {
|
|
95
99
|
// throws user callback exceptions in next tick
|
|
96
100
|
setTimeout(() => { throw e; }, 0);
|
|
@@ -98,12 +102,12 @@ export function readinessManagerFactory(
|
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
function checkIsReadyOrUpdate(
|
|
105
|
+
function checkIsReadyOrUpdate(metadata: SplitIO.SdkUpdateMetadata) {
|
|
102
106
|
if (isDestroyed) return;
|
|
103
107
|
if (isReady) {
|
|
104
108
|
try {
|
|
105
109
|
syncLastUpdate();
|
|
106
|
-
gate.emit(SDK_UPDATE,
|
|
110
|
+
gate.emit(SDK_UPDATE, metadata);
|
|
107
111
|
} catch (e) {
|
|
108
112
|
// throws user callback exceptions in next tick
|
|
109
113
|
setTimeout(() => { throw e; }, 0);
|
|
@@ -114,11 +118,20 @@ export function readinessManagerFactory(
|
|
|
114
118
|
isReady = true;
|
|
115
119
|
try {
|
|
116
120
|
syncLastUpdate();
|
|
121
|
+
const wasReadyFromCache = isReadyFromCache;
|
|
117
122
|
if (!isReadyFromCache) {
|
|
118
123
|
isReadyFromCache = true;
|
|
119
|
-
|
|
124
|
+
const metadataFromCache: SplitIO.SdkReadyMetadata = {
|
|
125
|
+
initialCacheLoad: false,
|
|
126
|
+
lastUpdateTimestamp: lastUpdate
|
|
127
|
+
};
|
|
128
|
+
gate.emit(SDK_READY_FROM_CACHE, metadataFromCache);
|
|
120
129
|
}
|
|
121
|
-
|
|
130
|
+
const metadataReady: SplitIO.SdkReadyMetadata = {
|
|
131
|
+
initialCacheLoad: wasReadyFromCache,
|
|
132
|
+
lastUpdateTimestamp: lastUpdate
|
|
133
|
+
};
|
|
134
|
+
gate.emit(SDK_READY, metadataReady);
|
|
122
135
|
} catch (e) {
|
|
123
136
|
// throws user callback exceptions in next tick
|
|
124
137
|
setTimeout(() => { throw e; }, 0);
|
package/src/readiness/types.ts
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import SplitIO from '../../types/splitio';
|
|
2
2
|
|
|
3
|
+
/** Readiness event types */
|
|
4
|
+
|
|
5
|
+
export type SDK_READY_TIMED_OUT = 'init::timeout'
|
|
6
|
+
export type SDK_READY = 'init::ready'
|
|
7
|
+
export type SDK_READY_FROM_CACHE = 'init::cache-ready'
|
|
8
|
+
export type SDK_UPDATE = 'state::update'
|
|
9
|
+
export type SDK_DESTROY = 'state::destroy'
|
|
10
|
+
|
|
11
|
+
export type IReadinessEvent = SDK_READY_TIMED_OUT | SDK_READY | SDK_READY_FROM_CACHE | SDK_UPDATE | SDK_DESTROY
|
|
12
|
+
|
|
13
|
+
export interface IReadinessEventEmitter extends SplitIO.IEventEmitter {
|
|
14
|
+
emit(event: IReadinessEvent, ...args: any[]): boolean
|
|
15
|
+
on(event: SDK_READY, listener: (metadata: SplitIO.SdkReadyMetadata) => void): this;
|
|
16
|
+
on(event: SDK_READY_FROM_CACHE, listener: (metadata: SplitIO.SdkReadyMetadata) => void): this;
|
|
17
|
+
on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
|
|
18
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
19
|
+
once(event: SDK_READY, listener: (metadata: SplitIO.SdkReadyMetadata) => void): this;
|
|
20
|
+
once(event: SDK_READY_FROM_CACHE, listener: (metadata: SplitIO.SdkReadyMetadata) => void): this;
|
|
21
|
+
once(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
|
|
22
|
+
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
23
|
+
addListener(event: SDK_READY, listener: (metadata: SplitIO.SdkReadyMetadata) => void): this;
|
|
24
|
+
addListener(event: SDK_READY_FROM_CACHE, listener: (metadata: SplitIO.SdkReadyMetadata) => void): this;
|
|
25
|
+
addListener(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
|
|
26
|
+
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
27
|
+
}
|
|
3
28
|
/** Splits data emitter */
|
|
4
29
|
|
|
5
30
|
type SDK_SPLITS_ARRIVED = 'state::splits-arrived'
|
|
@@ -9,6 +34,7 @@ type ISplitsEvent = SDK_SPLITS_ARRIVED | SDK_SPLITS_CACHE_LOADED
|
|
|
9
34
|
export interface ISplitsEventEmitter extends SplitIO.IEventEmitter {
|
|
10
35
|
emit(event: ISplitsEvent, ...args: any[]): boolean
|
|
11
36
|
on(event: ISplitsEvent, listener: (...args: any[]) => void): this;
|
|
37
|
+
on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
|
|
12
38
|
once(event: ISplitsEvent, listener: (...args: any[]) => void): this;
|
|
13
39
|
splitsArrived: boolean
|
|
14
40
|
splitsCacheLoaded: boolean
|
|
@@ -24,23 +50,11 @@ type ISegmentsEvent = SDK_SEGMENTS_ARRIVED
|
|
|
24
50
|
export interface ISegmentsEventEmitter extends SplitIO.IEventEmitter {
|
|
25
51
|
emit(event: ISegmentsEvent, ...args: any[]): boolean
|
|
26
52
|
on(event: ISegmentsEvent, listener: (...args: any[]) => void): this;
|
|
53
|
+
on(event: SDK_UPDATE, listener: (metadata: SplitIO.SdkUpdateMetadata) => void): this;
|
|
27
54
|
once(event: ISegmentsEvent, listener: (...args: any[]) => void): this;
|
|
28
55
|
segmentsArrived: boolean
|
|
29
56
|
}
|
|
30
57
|
|
|
31
|
-
/** Readiness emitter */
|
|
32
|
-
|
|
33
|
-
export type SDK_READY_TIMED_OUT = 'init::timeout'
|
|
34
|
-
export type SDK_READY = 'init::ready'
|
|
35
|
-
export type SDK_READY_FROM_CACHE = 'init::cache-ready'
|
|
36
|
-
export type SDK_UPDATE = 'state::update'
|
|
37
|
-
export type SDK_DESTROY = 'state::destroy'
|
|
38
|
-
export type IReadinessEvent = SDK_READY_TIMED_OUT | SDK_READY | SDK_READY_FROM_CACHE | SDK_UPDATE | SDK_DESTROY
|
|
39
|
-
|
|
40
|
-
export interface IReadinessEventEmitter extends SplitIO.IEventEmitter {
|
|
41
|
-
emit(event: IReadinessEvent, ...args: any[]): boolean
|
|
42
|
-
}
|
|
43
|
-
|
|
44
58
|
/** Readiness manager */
|
|
45
59
|
|
|
46
60
|
export interface IReadinessManager {
|
|
@@ -9,6 +9,7 @@ import { ISettings } from '../../../types';
|
|
|
9
9
|
import { CONTROL } from '../../../utils/constants';
|
|
10
10
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
|
|
11
11
|
import { SYNC_OFFLINE_DATA, ERROR_SYNC_OFFLINE_LOADING } from '../../../logger/constants';
|
|
12
|
+
import { SdkUpdateMetadataKeys } from '../../../../types/splitio';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Offline equivalent of `splitChangesUpdaterFactory`
|
|
@@ -55,7 +56,7 @@ export function fromObjectUpdaterFactory(
|
|
|
55
56
|
splitsCache.clear(), // required to sync removed splits from mock
|
|
56
57
|
splitsCache.update(splits, [], Date.now())
|
|
57
58
|
]).then(() => {
|
|
58
|
-
readiness.splits.emit(SDK_SPLITS_ARRIVED);
|
|
59
|
+
readiness.splits.emit(SDK_SPLITS_ARRIVED, { type: SdkUpdateMetadataKeys.FLAGS_UPDATE, names: [] });
|
|
59
60
|
|
|
60
61
|
if (startingUp) {
|
|
61
62
|
startingUp = false;
|
|
@@ -63,7 +64,7 @@ export function fromObjectUpdaterFactory(
|
|
|
63
64
|
// Emits SDK_READY_FROM_CACHE
|
|
64
65
|
if (isCacheLoaded) readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
|
|
65
66
|
// Emits SDK_READY
|
|
66
|
-
readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
67
|
+
readiness.segments.emit(SDK_SEGMENTS_ARRIVED, { type: SdkUpdateMetadataKeys.SEGMENTS_UPDATE, names: [] });
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
70
|
return true;
|
|
@@ -9,6 +9,7 @@ import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../../readiness/consta
|
|
|
9
9
|
import { POLLING_SMART_PAUSING, POLLING_START, POLLING_STOP } from '../../logger/constants';
|
|
10
10
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
11
11
|
import { usesSegmentsSync } from '../../storages/AbstractSplitsCacheSync';
|
|
12
|
+
import { SdkUpdateMetadata } from '../../../types/splitio';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Expose start / stop mechanism for polling data from services.
|
|
@@ -59,8 +60,8 @@ export function pollingManagerCSFactory(
|
|
|
59
60
|
const mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
60
61
|
|
|
61
62
|
// smart ready
|
|
62
|
-
function smartReady() {
|
|
63
|
-
if (!readiness.isReady() && !usesSegmentsSync(storage)) readiness.segments.emit(SDK_SEGMENTS_ARRIVED);
|
|
63
|
+
function smartReady(metadata: SdkUpdateMetadata) {
|
|
64
|
+
if (!readiness.isReady() && !usesSegmentsSync(storage)) readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
64
65
|
}
|
|
65
66
|
if (!usesSegmentsSync(storage)) setTimeout(smartReady, 0);
|
|
66
67
|
else readiness.splits.once(SDK_SPLITS_ARRIVED, smartReady);
|
|
@@ -9,6 +9,7 @@ import { MySegmentsData } from '../types';
|
|
|
9
9
|
import { IMembershipsResponse } from '../../../dtos/types';
|
|
10
10
|
import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
11
11
|
import { usesSegmentsSync } from '../../../storages/AbstractSplitsCacheSync';
|
|
12
|
+
import { SdkUpdateMetadataKeys } from '../../../../types/splitio';
|
|
12
13
|
|
|
13
14
|
type IMySegmentsUpdater = (segmentsData?: MySegmentsData, noCache?: boolean, till?: number) => Promise<boolean>
|
|
14
15
|
|
|
@@ -56,7 +57,7 @@ export function mySegmentsUpdaterFactory(
|
|
|
56
57
|
// Notify update if required
|
|
57
58
|
if (usesSegmentsSync(storage) && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
58
59
|
readyOnAlreadyExistentState = false;
|
|
59
|
-
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED);
|
|
60
|
+
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED, { type: SdkUpdateMetadataKeys.SEGMENTS_UPDATE, names: [] });
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -5,6 +5,8 @@ import { SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
|
|
|
5
5
|
import { ILogger } from '../../../logger/types';
|
|
6
6
|
import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC_SEGMENTS } from '../../../logger/constants';
|
|
7
7
|
import { timeout } from '../../../utils/promise/timeout';
|
|
8
|
+
import { SdkUpdateMetadata, SdkUpdateMetadataKeys } from '../../../../types/splitio';
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
type ISegmentChangesUpdater = (fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number) => Promise<boolean>
|
|
10
12
|
|
|
@@ -37,7 +39,7 @@ export function segmentChangesUpdaterFactory(
|
|
|
37
39
|
|
|
38
40
|
function updateSegment(segmentName: string, noCache?: boolean, till?: number, fetchOnlyNew?: boolean, retries?: number): Promise<boolean> {
|
|
39
41
|
log.debug(`${LOG_PREFIX_SYNC_SEGMENTS}Processing segment ${segmentName}`);
|
|
40
|
-
|
|
42
|
+
const sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
41
43
|
|
|
42
44
|
return sincePromise.then(since => {
|
|
43
45
|
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
@@ -83,7 +85,11 @@ export function segmentChangesUpdaterFactory(
|
|
|
83
85
|
// if at least one segment fetch succeeded, mark segments ready
|
|
84
86
|
if (shouldUpdateFlags.some(update => update) || readyOnAlreadyExistentState) {
|
|
85
87
|
readyOnAlreadyExistentState = false;
|
|
86
|
-
|
|
88
|
+
const metadata: SdkUpdateMetadata = {
|
|
89
|
+
type: SdkUpdateMetadataKeys.SEGMENTS_UPDATE,
|
|
90
|
+
names: []
|
|
91
|
+
};
|
|
92
|
+
if (readiness) readiness.segments.emit(SDK_SEGMENTS_ARRIVED, metadata);
|
|
87
93
|
}
|
|
88
94
|
return true;
|
|
89
95
|
});
|
|
@@ -10,6 +10,7 @@ import { startsWith } from '../../../utils/lang';
|
|
|
10
10
|
import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
|
|
11
11
|
import { setToArray } from '../../../utils/lang/sets';
|
|
12
12
|
import { SPLIT_UPDATE } from '../../streaming/constants';
|
|
13
|
+
import { SdkUpdateMetadata, SdkUpdateMetadataKeys } from '../../../../types/splitio';
|
|
13
14
|
|
|
14
15
|
export type InstantUpdate = { payload: ISplit | IRBSegment, changeNumber: number, type: string };
|
|
15
16
|
type SplitChangesUpdater = (noCache?: boolean, till?: number, instantUpdate?: InstantUpdate) => Promise<boolean>
|
|
@@ -54,7 +55,8 @@ export function parseSegments(ruleEntity: ISplit | IRBSegment, matcherType: type
|
|
|
54
55
|
|
|
55
56
|
interface ISplitMutations<T extends ISplit | IRBSegment> {
|
|
56
57
|
added: T[],
|
|
57
|
-
removed: T[]
|
|
58
|
+
removed: T[],
|
|
59
|
+
names: string[]
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
/**
|
|
@@ -95,9 +97,10 @@ export function computeMutation<T extends ISplit | IRBSegment>(rules: Array<T>,
|
|
|
95
97
|
} else {
|
|
96
98
|
accum.removed.push(ruleEntity);
|
|
97
99
|
}
|
|
100
|
+
accum.names.push(ruleEntity.name);
|
|
98
101
|
|
|
99
102
|
return accum;
|
|
100
|
-
}, { added: [], removed: [] } as ISplitMutations<T>);
|
|
103
|
+
}, { added: [], removed: [], names: [] } as ISplitMutations<T>);
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
/**
|
|
@@ -165,9 +168,11 @@ export function splitChangesUpdaterFactory(
|
|
|
165
168
|
.then((splitChanges: ISplitChangesResponse) => {
|
|
166
169
|
const usedSegments = new Set<string>();
|
|
167
170
|
|
|
171
|
+
let updatedFlags: string[] = [];
|
|
168
172
|
let ffUpdate: MaybeThenable<boolean> = false;
|
|
169
173
|
if (splitChanges.ff) {
|
|
170
|
-
const { added, removed } = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation);
|
|
174
|
+
const { added, removed, names } = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation);
|
|
175
|
+
updatedFlags = names;
|
|
171
176
|
log.debug(SYNC_SPLITS_UPDATE, [added.length, removed.length]);
|
|
172
177
|
ffUpdate = splits.update(added, removed, splitChanges.ff.t);
|
|
173
178
|
}
|
|
@@ -192,8 +197,12 @@ export function splitChangesUpdaterFactory(
|
|
|
192
197
|
return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
|
|
193
198
|
.catch(() => false /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
|
|
194
199
|
.then(emitSplitsArrivedEvent => {
|
|
200
|
+
const metadata: SdkUpdateMetadata = {
|
|
201
|
+
type: updatedFlags.length > 0 ? SdkUpdateMetadataKeys.FLAGS_UPDATE : SdkUpdateMetadataKeys.SEGMENTS_UPDATE,
|
|
202
|
+
names: updatedFlags.length > 0 ? updatedFlags : []
|
|
203
|
+
};
|
|
195
204
|
// emit SDK events
|
|
196
|
-
if (emitSplitsArrivedEvent) splitsEventEmitter.emit(SDK_SPLITS_ARRIVED);
|
|
205
|
+
if (emitSplitsArrivedEvent) splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, metadata);
|
|
197
206
|
return true;
|
|
198
207
|
});
|
|
199
208
|
}
|
|
@@ -38,7 +38,7 @@ export function submitterManagerFactory(params: ISdkFactoryContextSync): ISubmit
|
|
|
38
38
|
execute(onlyTelemetry?: boolean) {
|
|
39
39
|
const promises = onlyTelemetry ? [] : submitters.map(submitter => submitter.execute());
|
|
40
40
|
if (telemetrySubmitter) promises.push(telemetrySubmitter.execute());
|
|
41
|
-
return Promise.all(promises);
|
|
41
|
+
return Promise.all(promises).then(() => { });
|
|
42
42
|
},
|
|
43
43
|
|
|
44
44
|
isExecuting() {
|
|
@@ -237,5 +237,5 @@ export type TelemetryConfigStatsPayload = TelemetryConfigStats & {
|
|
|
237
237
|
export interface ISubmitterManager extends ISyncTask {
|
|
238
238
|
start(onlyTelemetry?: boolean): void,
|
|
239
239
|
stop(allExceptTelemetry?: boolean): void,
|
|
240
|
-
execute(onlyTelemetry?: boolean): Promise<
|
|
240
|
+
execute(onlyTelemetry?: boolean): Promise<void>
|
|
241
241
|
}
|
package/src/sync/types.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface ISyncTask<Input extends any[] = [], Output = any> extends ITask
|
|
|
37
37
|
/** SyncManager */
|
|
38
38
|
|
|
39
39
|
export interface ISyncManager extends ITask {
|
|
40
|
-
flush(): Promise<
|
|
40
|
+
flush(): Promise<void>,
|
|
41
41
|
pushManager?: IPushManager,
|
|
42
42
|
pollingManager?: IPollingManager,
|
|
43
43
|
submitterManager?: ISubmitterManager
|
package/types/splitio.d.ts
CHANGED
|
@@ -492,6 +492,52 @@ declare namespace SplitIO {
|
|
|
492
492
|
removeItem(key: string): void | Promise<void>;
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
+
/**
|
|
496
|
+
* Metadata keys for SDK update events.
|
|
497
|
+
*/
|
|
498
|
+
const enum SdkUpdateMetadataKeys {
|
|
499
|
+
/**
|
|
500
|
+
* The update event emitted when the SDK cache is updated with new data for flags.
|
|
501
|
+
*/
|
|
502
|
+
FLAGS_UPDATE = 'FLAGS_UPDATE',
|
|
503
|
+
/**
|
|
504
|
+
* The update event emitted when the SDK cache is updated with new data for segments.
|
|
505
|
+
*/
|
|
506
|
+
SEGMENTS_UPDATE = 'SEGMENTS_UPDATE'
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Metadata for the update event emitted when the SDK cache is updated with new data for flags or segments.
|
|
511
|
+
*/
|
|
512
|
+
type SdkUpdateMetadata = {
|
|
513
|
+
/**
|
|
514
|
+
* The type of update event.
|
|
515
|
+
*/
|
|
516
|
+
type: SdkUpdateMetadataKeys.FLAGS_UPDATE | SdkUpdateMetadataKeys.SEGMENTS_UPDATE
|
|
517
|
+
/**
|
|
518
|
+
* The names of the flags or segments that were updated.
|
|
519
|
+
*/
|
|
520
|
+
names: string[]
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Metadata for the ready events emitted when the SDK is ready to evaluate feature flags.
|
|
525
|
+
*/
|
|
526
|
+
type SdkReadyMetadata = {
|
|
527
|
+
/**
|
|
528
|
+
* Indicates whether the SDK was loaded from cache initially.
|
|
529
|
+
* - `true` when SDK_READY_FROM_CACHE is emitted from cache (before SDK_READY)
|
|
530
|
+
* - `true` when SDK_READY is emitted and the SDK was ready from cache first
|
|
531
|
+
* - `false` when SDK_READY_FROM_CACHE is emitted because SDK became ready without cache
|
|
532
|
+
* - `false` when SDK_READY is emitted and the SDK was not ready from cache
|
|
533
|
+
*/
|
|
534
|
+
initialCacheLoad: boolean
|
|
535
|
+
/**
|
|
536
|
+
* Timestamp in milliseconds since epoch when the event was emitted.
|
|
537
|
+
*/
|
|
538
|
+
lastUpdateTimestamp: number
|
|
539
|
+
}
|
|
540
|
+
|
|
495
541
|
/**
|
|
496
542
|
* EventEmitter interface based on a subset of the Node.js EventEmitter methods.
|
|
497
543
|
*/
|
|
@@ -509,8 +555,17 @@ declare namespace SplitIO {
|
|
|
509
555
|
* @see {@link https://nodejs.org/api/events.html}
|
|
510
556
|
*/
|
|
511
557
|
interface EventEmitter extends IEventEmitter {
|
|
558
|
+
addListener(event: EventConsts['SDK_READY'], listener: (metadata: SdkReadyMetadata) => void): this;
|
|
559
|
+
addListener(event: EventConsts['SDK_READY_FROM_CACHE'], listener: (metadata: SdkReadyMetadata) => void): this;
|
|
560
|
+
addListener(event: EventConsts['SDK_UPDATE'], listener: (metadata: SdkUpdateMetadata) => void): this;
|
|
512
561
|
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
562
|
+
on(event: EventConsts['SDK_READY'], listener: (metadata: SdkReadyMetadata) => void): this;
|
|
563
|
+
on(event: EventConsts['SDK_READY_FROM_CACHE'], listener: (metadata: SdkReadyMetadata) => void): this;
|
|
564
|
+
on(event: EventConsts['SDK_UPDATE'], listener: (metadata: SdkUpdateMetadata) => void): this;
|
|
513
565
|
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
566
|
+
once(event: EventConsts['SDK_READY'], listener: (metadata: SdkReadyMetadata) => void): this;
|
|
567
|
+
once(event: EventConsts['SDK_READY_FROM_CACHE'], listener: (metadata: SdkReadyMetadata) => void): this;
|
|
568
|
+
once(event: EventConsts['SDK_UPDATE'], listener: (metadata: SdkUpdateMetadata) => void): this;
|
|
514
569
|
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
515
570
|
removeListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
516
571
|
off(event: string | symbol, listener: (...args: any[]) => void): this;
|