@splitsoftware/splitio-commons 1.3.0 → 1.3.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 CHANGED
@@ -1,3 +1,7 @@
1
+ 1.3.1 (April 19, 2022)
2
+ - Bugfixing - Added peer dependencies to avoid issues when requiring some third-party dependencies used by modules of the package (Related to issue https://github.com/splitio/javascript-client/issues/662).
3
+ - Bugfixing - Updated `ready` method to rejects the promise with an Error object instead of a string value (Related to issue https://github.com/splitio/javascript-client/issues/654).
4
+
1
5
  1.3.0 (April 6, 2022)
2
6
  - Added user consent feature to allow delaying or disabling the data tracking from SDK until user consent is explicitly granted or declined. Read more in our docs.
3
7
  - Added `scheduler.impressionsQueueSize` property to SDK configuration to limit the amount of impressions tracked in memory. Read more in our docs.
@@ -44,7 +44,7 @@ function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, internalRea
44
44
  });
45
45
  // default onRejected handler, that just logs the error, if ready promise doesn't have one.
46
46
  function defaultOnRejected(err) {
47
- log.error(err);
47
+ log.error(err && err.message);
48
48
  }
49
49
  function generateReadyPromise() {
50
50
  var promise = (0, wrapper_1.promiseWrapper)(new Promise(function (resolve, reject) {
@@ -54,7 +54,9 @@ function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, internalRea
54
54
  log.warn(constants_2.CLIENT_NO_LISTENER);
55
55
  resolve();
56
56
  });
57
- readinessManager.gate.once(constants_1.SDK_READY_TIMED_OUT, reject);
57
+ readinessManager.gate.once(constants_1.SDK_READY_TIMED_OUT, function (message) {
58
+ reject(new Error(message));
59
+ });
58
60
  }), defaultOnRejected);
59
61
  return promise;
60
62
  }
@@ -97,7 +99,7 @@ function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, internalRea
97
99
  ready: function () {
98
100
  if (readinessManager.hasTimedout()) {
99
101
  if (!readinessManager.isReady()) {
100
- return (0, wrapper_1.promiseWrapper)(Promise.reject('Split SDK has emitted SDK_READY_TIMED_OUT event.'), defaultOnRejected);
102
+ return (0, wrapper_1.promiseWrapper)(Promise.reject(new Error('Split SDK has emitted SDK_READY_TIMED_OUT event.')), defaultOnRejected);
101
103
  }
102
104
  else {
103
105
  return Promise.resolve();
@@ -41,7 +41,7 @@ export function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, inte
41
41
  });
42
42
  // default onRejected handler, that just logs the error, if ready promise doesn't have one.
43
43
  function defaultOnRejected(err) {
44
- log.error(err);
44
+ log.error(err && err.message);
45
45
  }
46
46
  function generateReadyPromise() {
47
47
  var promise = promiseWrapper(new Promise(function (resolve, reject) {
@@ -51,7 +51,9 @@ export function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, inte
51
51
  log.warn(CLIENT_NO_LISTENER);
52
52
  resolve();
53
53
  });
54
- readinessManager.gate.once(SDK_READY_TIMED_OUT, reject);
54
+ readinessManager.gate.once(SDK_READY_TIMED_OUT, function (message) {
55
+ reject(new Error(message));
56
+ });
55
57
  }), defaultOnRejected);
56
58
  return promise;
57
59
  }
@@ -94,7 +96,7 @@ export function sdkReadinessManagerFactory(log, EventEmitter, readyTimeout, inte
94
96
  ready: function () {
95
97
  if (readinessManager.hasTimedout()) {
96
98
  if (!readinessManager.isReady()) {
97
- return promiseWrapper(Promise.reject('Split SDK has emitted SDK_READY_TIMED_OUT event.'), defaultOnRejected);
99
+ return promiseWrapper(Promise.reject(new Error('Split SDK has emitted SDK_READY_TIMED_OUT event.')), defaultOnRejected);
98
100
  }
99
101
  else {
100
102
  return Promise.resolve();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Split Javascript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -46,6 +46,18 @@
46
46
  "dependencies": {
47
47
  "tslib": "^2.3.1"
48
48
  },
49
+ "peerDependencies": {
50
+ "js-yaml": "^3.13.1",
51
+ "ioredis": "^4.28.0"
52
+ },
53
+ "peerDependenciesMeta": {
54
+ "js-yaml": {
55
+ "optional": true
56
+ },
57
+ "ioredis": {
58
+ "optional": true
59
+ }
60
+ },
49
61
  "devDependencies": {
50
62
  "@types/google.analytics": "0.0.40",
51
63
  "@types/ioredis": "^4.28.0",
@@ -62,7 +74,7 @@
62
74
  "ioredis": "^4.28.0",
63
75
  "jest": "^27.2.3",
64
76
  "jest-localstorage-mock": "^2.4.3",
65
- "js-yaml": "^3.14.0",
77
+ "js-yaml": "^3.13.1",
66
78
  "lodash": "^4.17.21",
67
79
  "node-fetch": "^2.6.7",
68
80
  "redis-server": "1.2.2",
@@ -51,7 +51,7 @@ export function sdkReadinessManagerFactory(
51
51
 
52
52
  // default onRejected handler, that just logs the error, if ready promise doesn't have one.
53
53
  function defaultOnRejected(err: any) {
54
- log.error(err);
54
+ log.error(err && err.message);
55
55
  }
56
56
 
57
57
  function generateReadyPromise() {
@@ -62,7 +62,9 @@ export function sdkReadinessManagerFactory(
62
62
  if (readyCbCount === internalReadyCbCount && !promise.hasOnFulfilled()) log.warn(CLIENT_NO_LISTENER);
63
63
  resolve();
64
64
  });
65
- readinessManager.gate.once(SDK_READY_TIMED_OUT, reject);
65
+ readinessManager.gate.once(SDK_READY_TIMED_OUT, (message: string) => {
66
+ reject(new Error(message));
67
+ });
66
68
  }), defaultOnRejected);
67
69
 
68
70
  return promise;
@@ -106,10 +108,10 @@ export function sdkReadinessManagerFactory(
106
108
  * @function ready
107
109
  * @returns {Promise<void>}
108
110
  */
109
- ready: () => {
111
+ ready() {
110
112
  if (readinessManager.hasTimedout()) {
111
113
  if (!readinessManager.isReady()) {
112
- return promiseWrapper(Promise.reject('Split SDK has emitted SDK_READY_TIMED_OUT event.'), defaultOnRejected);
114
+ return promiseWrapper(Promise.reject(new Error('Split SDK has emitted SDK_READY_TIMED_OUT event.')), defaultOnRejected);
113
115
  } else {
114
116
  return Promise.resolve();
115
117
  }
@@ -118,7 +120,7 @@ export function sdkReadinessManagerFactory(
118
120
  },
119
121
 
120
122
  // Expose status for internal purposes only. Not considered part of the public API, and might be updated eventually.
121
- __getStatus: () => {
123
+ __getStatus() {
122
124
  return {
123
125
  isReady: readinessManager.isReady(),
124
126
  isReadyFromCache: readinessManager.isReadyFromCache(),
@@ -74,8 +74,8 @@ export function impressionsTrackerFactory(
74
74
  // copy of impression, to avoid unexpected behaviour if modified by integrations or impressionListener
75
75
  impression: objectAssign({}, impressions[i]),
76
76
  attributes,
77
- ip: ip as string,
78
- hostname: hostname as string,
77
+ ip,
78
+ hostname,
79
79
  sdkLanguageVersion: version
80
80
  };
81
81
 
package/src/types.ts CHANGED
@@ -535,8 +535,8 @@ export namespace SplitIO {
535
535
  export type ImpressionData = {
536
536
  impression: ImpressionDTO,
537
537
  attributes?: SplitIO.Attributes,
538
- ip: string,
539
- hostname: string,
538
+ ip: string| false,
539
+ hostname: string | false,
540
540
  sdkLanguageVersion: string
541
541
  };
542
542
  /**
@@ -1,4 +1,4 @@
1
- import { ImpressionDataType, EventDataType, StreamingEvent, Method, OperationType } from '../../sync/submitters/types';
1
+ import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies } from '../../sync/submitters/types';
2
2
  import { TelemetryCacheSync } from '../types';
3
3
  export declare class TelemetryCacheInMemory implements TelemetryCacheSync {
4
4
  private timeUntilReady?;
@@ -17,16 +17,14 @@ export declare class TelemetryCacheInMemory implements TelemetryCacheSync {
17
17
  getEventStats(type: EventDataType): number;
18
18
  recordEventStats(type: EventDataType, count: number): void;
19
19
  private lastSync;
20
- getLastSynchronization(): Record<OperationType, number | undefined>;
20
+ getLastSynchronization(): LastSync;
21
21
  recordSuccessfulSync(resource: OperationType, timeMs: number): void;
22
22
  private httpErrors;
23
- popHttpErrors(): Record<OperationType, {
24
- [statusCode: string]: number;
25
- }>;
26
- recordSyncError(resource: OperationType, status: number): void;
23
+ popHttpErrors(): HttpErrors;
24
+ recordHttpError(resource: OperationType, status: number): void;
27
25
  private httpLatencies;
28
- popHttpLatencies(): Record<OperationType, number[]>;
29
- recordSyncLatency(resource: OperationType, latencyMs: number): void;
26
+ popHttpLatencies(): HttpLatencies;
27
+ recordHttpLatency(resource: OperationType, latencyMs: number): void;
30
28
  private authRejections;
31
29
  popAuthRejections(): number;
32
30
  recordAuthRejections(): void;
@@ -43,9 +41,9 @@ export declare class TelemetryCacheInMemory implements TelemetryCacheSync {
43
41
  getSessionLength(): number | undefined;
44
42
  recordSessionLength(ms: number): void;
45
43
  private exceptions;
46
- popExceptions(): Record<Method, number>;
44
+ popExceptions(): MethodExceptions;
47
45
  recordException(method: Method): void;
48
46
  private latencies;
49
- popLatencies(): Record<Method, number[]>;
47
+ popLatencies(): MethodLatencies;
50
48
  recordLatency(method: Method, latencyMs: number): void;
51
49
  }
@@ -0,0 +1,19 @@
1
+ import { ILogger } from '../../logger/types';
2
+ import { Method } from '../../sync/submitters/types';
3
+ import { KeyBuilderSS } from '../KeyBuilderSS';
4
+ import { TelemetryCacheAsync } from '../types';
5
+ import { Redis } from 'ioredis';
6
+ export declare class TelemetryCacheInRedis implements TelemetryCacheAsync {
7
+ private readonly log;
8
+ private readonly keys;
9
+ private readonly redis;
10
+ /**
11
+ * Create a Telemetry cache that uses a storage wrapper.
12
+ * @param log Logger instance.
13
+ * @param keys Key builder.
14
+ * @param redis Redis client.
15
+ */
16
+ constructor(log: ILogger, keys: KeyBuilderSS, redis: Redis);
17
+ recordLatency(method: Method, latencyMs: number): Promise<number | void>;
18
+ recordException(method: Method): Promise<number | void>;
19
+ }
@@ -1,2 +1,18 @@
1
- export declare class TelemetryCachePluggable {
1
+ import { ILogger } from '../../logger/types';
2
+ import { Method } from '../../sync/submitters/types';
3
+ import { KeyBuilderSS } from '../KeyBuilderSS';
4
+ import { IPluggableStorageWrapper, TelemetryCacheAsync } from '../types';
5
+ export declare class TelemetryCachePluggable implements TelemetryCacheAsync {
6
+ private readonly log;
7
+ private readonly keys;
8
+ private readonly wrapper;
9
+ /**
10
+ * Create a Telemetry cache that uses a storage wrapper.
11
+ * @param log Logger instance.
12
+ * @param keys Key builder.
13
+ * @param wrapper Adapted wrapper storage.
14
+ */
15
+ constructor(log: ILogger, keys: KeyBuilderSS, wrapper: IPluggableStorageWrapper);
16
+ recordLatency(method: Method, latencyMs: number): Promise<number | void>;
17
+ recordException(method: Method): Promise<number | void>;
2
18
  }
@@ -1,17 +1,27 @@
1
1
  import { ISyncTask, ITimeTracker } from '../types';
2
- import { IPostMetricsUsage } from '../../services/types';
2
+ import { ISplitApi } from '../../services/types';
3
3
  import { IStorageSync, TelemetryCacheSync } from '../../storages/types';
4
- import { TelemetryStatsPayload } from './types';
5
- import { ILogger } from '../../logger/types';
4
+ import { TelemetryUsageStatsPayload, TelemetryConfigStatsPayload } from './types';
5
+ import { IReadinessManager } from '../../readiness/types';
6
+ import { ISettings } from '../../types';
6
7
  /**
7
8
  * Converts `impressions` data from cache into request payload.
8
9
  */
9
- export declare function telemetryCacheAdapter(telemetryCache: TelemetryCacheSync, storage: IStorageSync): {
10
+ export declare function telemetryCacheStatsAdapter({ splits, segments, telemetry }: IStorageSync & {
11
+ telemetry: TelemetryCacheSync;
12
+ }): {
10
13
  isEmpty(): boolean;
11
14
  clear(): void;
12
- state(): TelemetryStatsPayload;
15
+ state(): TelemetryUsageStatsPayload;
16
+ };
17
+ export declare function telemetryCacheConfigAdapter(settings: ISettings, telemetryCache: TelemetryCacheSync): {
18
+ isEmpty(): boolean;
19
+ clear(): void;
20
+ state(): TelemetryConfigStatsPayload;
13
21
  };
14
22
  /**
15
23
  * Sync task that periodically posts impressions data
16
24
  */
17
- export declare function telemetrySyncTaskFactory(log: ILogger, postMetricsUsage: IPostMetricsUsage, telemetryCache: TelemetryCacheSync, telemetryRefreshRate: number, latencyTracker: ITimeTracker, storage: IStorageSync): ISyncTask;
25
+ export declare function telemetrySyncTaskFactory(settings: ISettings, { postMetricsUsage, postMetricsConfig }: ISplitApi, storage: IStorageSync & {
26
+ telemetry: TelemetryCacheSync;
27
+ }, telemetryRefreshRate: number, readiness: IReadinessManager, latencyTracker?: ITimeTracker): ISyncTask;
@@ -0,0 +1,4 @@
1
+ import { TelemetryCacheAsync, TelemetryCacheSync } from '../storages/types';
2
+ import { ISettings } from '../types';
3
+ import { ITelemetryTracker } from './types';
4
+ export declare function telemetryTrackerFactory(settings: ISettings, telemetryCache?: TelemetryCacheAsync | TelemetryCacheSync, now?: () => number): ITelemetryTracker;
package/types/types.d.ts CHANGED
@@ -526,8 +526,8 @@ export declare namespace SplitIO {
526
526
  type ImpressionData = {
527
527
  impression: ImpressionDTO;
528
528
  attributes?: SplitIO.Attributes;
529
- ip: string;
530
- hostname: string;
529
+ ip: string | false;
530
+ hostname: string | false;
531
531
  sdkLanguageVersion: string;
532
532
  };
533
533
  /**