@splitsoftware/splitio-commons 1.17.0-rc.1 → 1.17.0-rc.3

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 CHANGED
@@ -1,5 +1,6 @@
1
- 1.17.0 (August XXX, 2024)
1
+ 1.17.0 (September 6, 2024)
2
2
  - Added `sync.requestOptions.getHeaderOverrides` configuration option to enhance SDK HTTP request Headers for Authorization Frameworks.
3
+ - Added lastUpdate property to ReadinessManager to keep track of the timestamp of the last SDK event, used on React and Redux SDKs.
3
4
  - Updated some transitive dependencies for vulnerability fixes.
4
5
 
5
6
  1.16.0 (June 13, 2024)
@@ -31,6 +31,12 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
31
31
  if (splits === void 0) { splits = splitsEventEmitterFactory(EventEmitter); }
32
32
  var segments = segmentsEventEmitterFactory(EventEmitter);
33
33
  var gate = new EventEmitter();
34
+ var lastUpdate = 0;
35
+ function syncLastUpdate() {
36
+ var dateNow = Date.now();
37
+ // ensure lastUpdate is always increasing per event, is case Date.now() is mocked or its value is the same
38
+ lastUpdate = dateNow > lastUpdate ? dateNow : lastUpdate + 1;
39
+ }
34
40
  // emit SDK_READY_FROM_CACHE
35
41
  var isReadyFromCache = false;
36
42
  if (splits.splitsCacheLoaded)
@@ -43,6 +49,7 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
43
49
  if (hasTimedout)
44
50
  return;
45
51
  hasTimedout = true;
52
+ syncLastUpdate();
46
53
  gate.emit(constants_1.SDK_READY_TIMED_OUT, 'Split SDK emitted SDK_READY_TIMED_OUT event.');
47
54
  }
48
55
  var readyTimeoutId;
@@ -59,6 +66,7 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
59
66
  // Don't emit SDK_READY_FROM_CACHE if SDK_READY has been emitted
60
67
  if (!isReady) {
61
68
  try {
69
+ syncLastUpdate();
62
70
  gate.emit(constants_1.SDK_READY_FROM_CACHE);
63
71
  }
64
72
  catch (e) {
@@ -70,6 +78,7 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
70
78
  function checkIsReadyOrUpdate(diff) {
71
79
  if (isReady) {
72
80
  try {
81
+ syncLastUpdate();
73
82
  gate.emit(constants_1.SDK_UPDATE, diff);
74
83
  }
75
84
  catch (e) {
@@ -82,6 +91,7 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
82
91
  clearTimeout(readyTimeoutId);
83
92
  isReady = true;
84
93
  try {
94
+ syncLastUpdate();
85
95
  gate.emit(constants_1.SDK_READY);
86
96
  }
87
97
  catch (e) {
@@ -109,6 +119,7 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
109
119
  setDestroyed: function () { isDestroyed = true; },
110
120
  destroy: function () {
111
121
  isDestroyed = true;
122
+ syncLastUpdate();
112
123
  segments.removeAllListeners();
113
124
  gate.removeAllListeners();
114
125
  clearTimeout(readyTimeoutId);
@@ -121,7 +132,8 @@ function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
121
132
  hasTimedout: function () { return hasTimedout; },
122
133
  isReadyFromCache: function () { return isReadyFromCache; },
123
134
  isDestroyed: function () { return isDestroyed; },
124
- isOperational: function () { return (isReady || isReadyFromCache) && !isDestroyed; }
135
+ isOperational: function () { return (isReady || isReadyFromCache) && !isDestroyed; },
136
+ lastUpdate: function () { return lastUpdate; }
125
137
  };
126
138
  }
127
139
  exports.readinessManagerFactory = readinessManagerFactory;
@@ -115,6 +115,7 @@ function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, readinessMa
115
115
  isOperational: readinessManager.isOperational(),
116
116
  hasTimedout: readinessManager.hasTimedout(),
117
117
  isDestroyed: readinessManager.isDestroyed(),
118
+ lastUpdate: readinessManager.lastUpdate(),
118
119
  };
119
120
  },
120
121
  })
@@ -18,20 +18,13 @@ var FORBIDDEN_HEADERS = new sets_1._Set([
18
18
  'keep-alive',
19
19
  'x-fastly-debug'
20
20
  ]);
21
- function copyToLowerCase(obj) {
22
- return Object.keys(obj).reduce(function (acc, key) {
23
- acc[key.toLowerCase()] = obj[key];
24
- return acc;
25
- }, {});
26
- }
27
21
  function decorateHeaders(settings, headers) {
28
22
  var _a;
29
23
  if ((_a = settings.sync.requestOptions) === null || _a === void 0 ? void 0 : _a.getHeaderOverrides) {
30
- headers = copyToLowerCase(headers);
31
24
  try {
32
- var headerOverrides_1 = copyToLowerCase(settings.sync.requestOptions.getHeaderOverrides({ headers: (0, objectAssign_1.objectAssign)({}, headers) }));
25
+ var headerOverrides_1 = settings.sync.requestOptions.getHeaderOverrides({ headers: (0, objectAssign_1.objectAssign)({}, headers) });
33
26
  Object.keys(headerOverrides_1)
34
- .filter(function (key) { return !FORBIDDEN_HEADERS.has(key); })
27
+ .filter(function (key) { return !FORBIDDEN_HEADERS.has(key.toLowerCase()); })
35
28
  .forEach(function (key) { return headers[key] = headerOverrides_1[key]; });
36
29
  }
37
30
  catch (e) {
@@ -28,6 +28,12 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
28
28
  if (splits === void 0) { splits = splitsEventEmitterFactory(EventEmitter); }
29
29
  var segments = segmentsEventEmitterFactory(EventEmitter);
30
30
  var gate = new EventEmitter();
31
+ var lastUpdate = 0;
32
+ function syncLastUpdate() {
33
+ var dateNow = Date.now();
34
+ // ensure lastUpdate is always increasing per event, is case Date.now() is mocked or its value is the same
35
+ lastUpdate = dateNow > lastUpdate ? dateNow : lastUpdate + 1;
36
+ }
31
37
  // emit SDK_READY_FROM_CACHE
32
38
  var isReadyFromCache = false;
33
39
  if (splits.splitsCacheLoaded)
@@ -40,6 +46,7 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
40
46
  if (hasTimedout)
41
47
  return;
42
48
  hasTimedout = true;
49
+ syncLastUpdate();
43
50
  gate.emit(SDK_READY_TIMED_OUT, 'Split SDK emitted SDK_READY_TIMED_OUT event.');
44
51
  }
45
52
  var readyTimeoutId;
@@ -56,6 +63,7 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
56
63
  // Don't emit SDK_READY_FROM_CACHE if SDK_READY has been emitted
57
64
  if (!isReady) {
58
65
  try {
66
+ syncLastUpdate();
59
67
  gate.emit(SDK_READY_FROM_CACHE);
60
68
  }
61
69
  catch (e) {
@@ -67,6 +75,7 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
67
75
  function checkIsReadyOrUpdate(diff) {
68
76
  if (isReady) {
69
77
  try {
78
+ syncLastUpdate();
70
79
  gate.emit(SDK_UPDATE, diff);
71
80
  }
72
81
  catch (e) {
@@ -79,6 +88,7 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
79
88
  clearTimeout(readyTimeoutId);
80
89
  isReady = true;
81
90
  try {
91
+ syncLastUpdate();
82
92
  gate.emit(SDK_READY);
83
93
  }
84
94
  catch (e) {
@@ -106,6 +116,7 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
106
116
  setDestroyed: function () { isDestroyed = true; },
107
117
  destroy: function () {
108
118
  isDestroyed = true;
119
+ syncLastUpdate();
109
120
  segments.removeAllListeners();
110
121
  gate.removeAllListeners();
111
122
  clearTimeout(readyTimeoutId);
@@ -118,6 +129,7 @@ export function readinessManagerFactory(EventEmitter, readyTimeout, splits) {
118
129
  hasTimedout: function () { return hasTimedout; },
119
130
  isReadyFromCache: function () { return isReadyFromCache; },
120
131
  isDestroyed: function () { return isDestroyed; },
121
- isOperational: function () { return (isReady || isReadyFromCache) && !isDestroyed; }
132
+ isOperational: function () { return (isReady || isReadyFromCache) && !isDestroyed; },
133
+ lastUpdate: function () { return lastUpdate; }
122
134
  };
123
135
  }
@@ -112,6 +112,7 @@ export function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, read
112
112
  isOperational: readinessManager.isOperational(),
113
113
  hasTimedout: readinessManager.hasTimedout(),
114
114
  isDestroyed: readinessManager.isDestroyed(),
115
+ lastUpdate: readinessManager.lastUpdate(),
115
116
  };
116
117
  },
117
118
  })
@@ -15,20 +15,13 @@ var FORBIDDEN_HEADERS = new _Set([
15
15
  'keep-alive',
16
16
  'x-fastly-debug'
17
17
  ]);
18
- function copyToLowerCase(obj) {
19
- return Object.keys(obj).reduce(function (acc, key) {
20
- acc[key.toLowerCase()] = obj[key];
21
- return acc;
22
- }, {});
23
- }
24
18
  export function decorateHeaders(settings, headers) {
25
19
  var _a;
26
20
  if ((_a = settings.sync.requestOptions) === null || _a === void 0 ? void 0 : _a.getHeaderOverrides) {
27
- headers = copyToLowerCase(headers);
28
21
  try {
29
- var headerOverrides_1 = copyToLowerCase(settings.sync.requestOptions.getHeaderOverrides({ headers: objectAssign({}, headers) }));
22
+ var headerOverrides_1 = settings.sync.requestOptions.getHeaderOverrides({ headers: objectAssign({}, headers) });
30
23
  Object.keys(headerOverrides_1)
31
- .filter(function (key) { return !FORBIDDEN_HEADERS.has(key); })
24
+ .filter(function (key) { return !FORBIDDEN_HEADERS.has(key.toLowerCase()); })
32
25
  .forEach(function (key) { return headers[key] = headerOverrides_1[key]; });
33
26
  }
34
27
  catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "1.17.0-rc.1",
3
+ "version": "1.17.0-rc.3",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -39,6 +39,13 @@ export function readinessManagerFactory(
39
39
  const segments: ISegmentsEventEmitter = segmentsEventEmitterFactory(EventEmitter);
40
40
  const gate: IReadinessEventEmitter = new EventEmitter();
41
41
 
42
+ let lastUpdate = 0;
43
+ function syncLastUpdate() {
44
+ const dateNow = Date.now();
45
+ // ensure lastUpdate is always increasing per event, is case Date.now() is mocked or its value is the same
46
+ lastUpdate = dateNow > lastUpdate ? dateNow : lastUpdate + 1;
47
+ }
48
+
42
49
  // emit SDK_READY_FROM_CACHE
43
50
  let isReadyFromCache = false;
44
51
  if (splits.splitsCacheLoaded) isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
@@ -50,6 +57,7 @@ export function readinessManagerFactory(
50
57
  function timeout() {
51
58
  if (hasTimedout) return;
52
59
  hasTimedout = true;
60
+ syncLastUpdate();
53
61
  gate.emit(SDK_READY_TIMED_OUT, 'Split SDK emitted SDK_READY_TIMED_OUT event.');
54
62
  }
55
63
 
@@ -70,6 +78,7 @@ export function readinessManagerFactory(
70
78
  // Don't emit SDK_READY_FROM_CACHE if SDK_READY has been emitted
71
79
  if (!isReady) {
72
80
  try {
81
+ syncLastUpdate();
73
82
  gate.emit(SDK_READY_FROM_CACHE);
74
83
  } catch (e) {
75
84
  // throws user callback exceptions in next tick
@@ -81,6 +90,7 @@ export function readinessManagerFactory(
81
90
  function checkIsReadyOrUpdate(diff: any) {
82
91
  if (isReady) {
83
92
  try {
93
+ syncLastUpdate();
84
94
  gate.emit(SDK_UPDATE, diff);
85
95
  } catch (e) {
86
96
  // throws user callback exceptions in next tick
@@ -91,6 +101,7 @@ export function readinessManagerFactory(
91
101
  clearTimeout(readyTimeoutId);
92
102
  isReady = true;
93
103
  try {
104
+ syncLastUpdate();
94
105
  gate.emit(SDK_READY);
95
106
  } catch (e) {
96
107
  // throws user callback exceptions in next tick
@@ -121,6 +132,7 @@ export function readinessManagerFactory(
121
132
 
122
133
  destroy() {
123
134
  isDestroyed = true;
135
+ syncLastUpdate();
124
136
 
125
137
  segments.removeAllListeners();
126
138
  gate.removeAllListeners();
@@ -134,7 +146,8 @@ export function readinessManagerFactory(
134
146
  hasTimedout() { return hasTimedout; },
135
147
  isReadyFromCache() { return isReadyFromCache; },
136
148
  isDestroyed() { return isDestroyed; },
137
- isOperational() { return (isReady || isReadyFromCache) && !isDestroyed; }
149
+ isOperational() { return (isReady || isReadyFromCache) && !isDestroyed; },
150
+ lastUpdate() { return lastUpdate; }
138
151
  };
139
152
 
140
153
  }
@@ -129,6 +129,7 @@ export function sdkReadinessManagerFactory(
129
129
  isOperational: readinessManager.isOperational(),
130
130
  hasTimedout: readinessManager.hasTimedout(),
131
131
  isDestroyed: readinessManager.isDestroyed(),
132
+ lastUpdate: readinessManager.lastUpdate(),
132
133
  };
133
134
  },
134
135
  }
@@ -53,6 +53,7 @@ export interface IReadinessManager {
53
53
  hasTimedout(): boolean,
54
54
  isDestroyed(): boolean,
55
55
  isOperational(): boolean,
56
+ lastUpdate(): number,
56
57
 
57
58
  timeout(): void,
58
59
  setDestroyed(): void,
@@ -18,20 +18,12 @@ const FORBIDDEN_HEADERS = new _Set([
18
18
  'x-fastly-debug'
19
19
  ]);
20
20
 
21
- function copyToLowerCase(obj: Record<string, string>) {
22
- return Object.keys(obj).reduce<Record<string, string>>((acc, key) => {
23
- acc[key.toLowerCase()] = obj[key];
24
- return acc;
25
- }, {});
26
- }
27
-
28
21
  export function decorateHeaders(settings: ISettings, headers: Record<string, string>) {
29
22
  if (settings.sync.requestOptions?.getHeaderOverrides) {
30
- headers = copyToLowerCase(headers);
31
23
  try {
32
- const headerOverrides = copyToLowerCase(settings.sync.requestOptions.getHeaderOverrides({ headers: objectAssign({}, headers) }));
24
+ const headerOverrides = settings.sync.requestOptions.getHeaderOverrides({ headers: objectAssign({}, headers) });
33
25
  Object.keys(headerOverrides)
34
- .filter(key => !FORBIDDEN_HEADERS.has(key))
26
+ .filter(key => !FORBIDDEN_HEADERS.has(key.toLowerCase()))
35
27
  .forEach(key => headers[key] = headerOverrides[key]);
36
28
  } catch (e) {
37
29
  settings.log.error('Problem adding custom headers to request decorator: ' + e);
@@ -41,6 +41,7 @@ export interface IReadinessManager {
41
41
  hasTimedout(): boolean;
42
42
  isDestroyed(): boolean;
43
43
  isOperational(): boolean;
44
+ lastUpdate(): number;
44
45
  timeout(): void;
45
46
  setDestroyed(): void;
46
47
  destroy(): void;
@@ -0,0 +1,9 @@
1
+ import { IPushManager } from './types';
2
+ import { IPollingManager } from '../polling/types';
3
+ import { ISdkFactoryContextSync } from '../../sdkFactory/types';
4
+ /**
5
+ * PushManager factory:
6
+ * - for server-side if key is not provided in settings.
7
+ * - for client-side, with support for multiple clients, if key is provided in settings
8
+ */
9
+ export declare function pushManagerFactory(params: ISdkFactoryContextSync, pollingManager: IPollingManager): IPushManager | undefined;
@@ -0,0 +1,9 @@
1
+ import { IPushManager } from './types';
2
+ import { IPollingManager } from '../polling/types';
3
+ import { ISdkFactoryContextSync } from '../../sdkFactory/types';
4
+ /**
5
+ * PushManager factory:
6
+ * - for server-side if key is not provided in settings.
7
+ * - for client-side, with support for multiple clients, if key is provided in settings
8
+ */
9
+ export declare function pushManagerFactory(params: ISdkFactoryContextSync, pollingManager: IPollingManager): IPushManager | undefined;