@splitsoftware/splitio-commons 1.3.1-rc.1 → 1.3.2-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.
Files changed (218) hide show
  1. package/cjs/consent/sdkUserConsent.js +1 -1
  2. package/cjs/listeners/browser.js +5 -4
  3. package/cjs/logger/constants.js +2 -1
  4. package/cjs/logger/messages/error.js +2 -1
  5. package/cjs/logger/messages/info.js +3 -3
  6. package/cjs/logger/messages/warn.js +2 -2
  7. package/cjs/sdkClient/client.js +17 -3
  8. package/cjs/sdkClient/sdkClient.js +4 -1
  9. package/cjs/sdkFactory/index.js +16 -19
  10. package/cjs/services/splitApi.js +15 -14
  11. package/cjs/services/splitHttpClient.js +4 -1
  12. package/cjs/storages/AbstractSegmentsCacheSync.js +0 -5
  13. package/cjs/storages/KeyBuilderSS.js +12 -19
  14. package/cjs/storages/findLatencyIndex.js +11 -6
  15. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +13 -1
  16. package/cjs/storages/inLocalStorage/index.js +4 -1
  17. package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
  18. package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -0
  19. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +6 -0
  20. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +6 -0
  21. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +165 -0
  22. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +29 -0
  23. package/cjs/storages/inRedis/index.js +2 -4
  24. package/cjs/storages/pluggable/TelemetryCachePluggable.js +27 -0
  25. package/cjs/storages/pluggable/index.js +2 -1
  26. package/cjs/sync/polling/pollingManagerCS.js +1 -1
  27. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +2 -2
  28. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +0 -3
  29. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -8
  30. package/cjs/sync/polling/updaters/splitChangesUpdater.js +3 -6
  31. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +20 -13
  32. package/cjs/sync/streaming/SSEHandler/index.js +21 -15
  33. package/cjs/sync/streaming/pushManager.js +7 -4
  34. package/cjs/sync/submitters/eventsSubmitter.js +28 -0
  35. package/cjs/sync/submitters/{impressionCountsSyncTask.js → impressionCountsSubmitter.js} +10 -7
  36. package/cjs/sync/submitters/{impressionsSyncTask.js → impressionsSubmitter.js} +8 -8
  37. package/cjs/sync/submitters/{submitterSyncTask.js → submitter.js} +34 -13
  38. package/cjs/sync/submitters/submitterManager.js +12 -10
  39. package/cjs/sync/submitters/telemetrySubmitter.js +128 -0
  40. package/cjs/sync/syncManagerOnline.js +6 -2
  41. package/cjs/trackers/eventTracker.js +5 -1
  42. package/cjs/trackers/impressionsTracker.js +9 -1
  43. package/cjs/trackers/telemetryTracker.js +65 -0
  44. package/cjs/utils/constants/index.js +40 -1
  45. package/cjs/utils/inputValidation/apiKey.js +12 -11
  46. package/cjs/utils/settingsValidation/index.js +20 -6
  47. package/cjs/utils/settingsValidation/url.js +4 -0
  48. package/cjs/utils/timeTracker/index.js +1 -0
  49. package/cjs/utils/timeTracker/timer.js +2 -2
  50. package/esm/consent/sdkUserConsent.js +1 -1
  51. package/esm/listeners/browser.js +3 -2
  52. package/esm/logger/constants.js +1 -0
  53. package/esm/logger/messages/error.js +2 -1
  54. package/esm/logger/messages/info.js +3 -3
  55. package/esm/logger/messages/warn.js +2 -2
  56. package/esm/sdkClient/client.js +18 -4
  57. package/esm/sdkClient/sdkClient.js +4 -1
  58. package/esm/sdkFactory/index.js +16 -19
  59. package/esm/services/splitApi.js +15 -14
  60. package/esm/services/splitHttpClient.js +4 -1
  61. package/esm/storages/AbstractSegmentsCacheSync.js +0 -5
  62. package/esm/storages/KeyBuilderSS.js +12 -19
  63. package/esm/storages/findLatencyIndex.js +11 -6
  64. package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +13 -1
  65. package/esm/storages/inLocalStorage/index.js +5 -2
  66. package/esm/storages/inMemory/InMemoryStorage.js +3 -1
  67. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -1
  68. package/esm/storages/inMemory/MySegmentsCacheInMemory.js +6 -0
  69. package/esm/storages/inMemory/SegmentsCacheInMemory.js +6 -0
  70. package/esm/storages/inMemory/TelemetryCacheInMemory.js +161 -0
  71. package/esm/storages/inRedis/TelemetryCacheInRedis.js +26 -0
  72. package/esm/storages/inRedis/index.js +2 -4
  73. package/esm/storages/pluggable/TelemetryCachePluggable.js +24 -0
  74. package/esm/storages/pluggable/index.js +2 -1
  75. package/esm/sync/polling/pollingManagerCS.js +1 -1
  76. package/esm/sync/polling/syncTasks/splitsSyncTask.js +2 -2
  77. package/esm/sync/polling/updaters/mySegmentsUpdater.js +0 -3
  78. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -8
  79. package/esm/sync/polling/updaters/splitChangesUpdater.js +3 -6
  80. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +8 -1
  81. package/esm/sync/streaming/SSEHandler/index.js +21 -15
  82. package/esm/sync/streaming/pushManager.js +7 -4
  83. package/esm/sync/submitters/eventsSubmitter.js +24 -0
  84. package/esm/sync/submitters/{impressionCountsSyncTask.js → impressionCountsSubmitter.js} +8 -5
  85. package/esm/sync/submitters/{impressionsSyncTask.js → impressionsSubmitter.js} +6 -6
  86. package/esm/sync/submitters/submitter.js +60 -0
  87. package/esm/sync/submitters/submitterManager.js +12 -10
  88. package/esm/sync/submitters/telemetrySubmitter.js +122 -0
  89. package/esm/sync/syncManagerOnline.js +6 -2
  90. package/esm/trackers/eventTracker.js +6 -2
  91. package/esm/trackers/impressionsTracker.js +10 -2
  92. package/esm/trackers/telemetryTracker.js +61 -0
  93. package/esm/utils/constants/index.js +38 -0
  94. package/esm/utils/inputValidation/apiKey.js +2 -1
  95. package/esm/utils/settingsValidation/index.js +18 -4
  96. package/esm/utils/settingsValidation/url.js +4 -0
  97. package/esm/utils/timeTracker/index.js +1 -0
  98. package/esm/utils/timeTracker/timer.js +2 -2
  99. package/package.json +1 -1
  100. package/src/consent/sdkUserConsent.ts +1 -1
  101. package/src/listeners/browser.ts +3 -2
  102. package/src/logger/constants.ts +1 -0
  103. package/src/logger/messages/error.ts +2 -1
  104. package/src/logger/messages/info.ts +3 -3
  105. package/src/logger/messages/warn.ts +2 -2
  106. package/src/sdkClient/client.ts +23 -4
  107. package/src/sdkClient/sdkClient.ts +4 -1
  108. package/src/sdkFactory/index.ts +22 -24
  109. package/src/sdkFactory/types.ts +32 -15
  110. package/src/services/splitApi.ts +17 -14
  111. package/src/services/splitHttpClient.ts +6 -3
  112. package/src/services/types.ts +7 -5
  113. package/src/storages/AbstractSegmentsCacheSync.ts +8 -3
  114. package/src/storages/KeyBuilderSS.ts +13 -50
  115. package/src/storages/findLatencyIndex.ts +12 -3
  116. package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +13 -1
  117. package/src/storages/inLocalStorage/index.ts +5 -2
  118. package/src/storages/inMemory/InMemoryStorage.ts +3 -1
  119. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -1
  120. package/src/storages/inMemory/MySegmentsCacheInMemory.ts +8 -0
  121. package/src/storages/inMemory/SegmentsCacheInMemory.ts +6 -0
  122. package/src/storages/inMemory/TelemetryCacheInMemory.ts +210 -0
  123. package/src/storages/inRedis/TelemetryCacheInRedis.ts +29 -0
  124. package/src/storages/inRedis/index.ts +2 -4
  125. package/src/storages/pluggable/TelemetryCachePluggable.ts +26 -0
  126. package/src/storages/pluggable/index.ts +2 -1
  127. package/src/storages/types.ts +84 -32
  128. package/src/sync/offline/syncManagerOffline.ts +4 -3
  129. package/src/sync/polling/pollingManagerCS.ts +3 -3
  130. package/src/sync/polling/pollingManagerSS.ts +2 -2
  131. package/src/sync/polling/syncTasks/splitsSyncTask.ts +2 -0
  132. package/src/sync/polling/updaters/mySegmentsUpdater.ts +0 -4
  133. package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -10
  134. package/src/sync/polling/updaters/splitChangesUpdater.ts +3 -6
  135. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +11 -1
  136. package/src/sync/streaming/SSEHandler/index.ts +21 -14
  137. package/src/sync/streaming/pushManager.ts +11 -7
  138. package/src/sync/submitters/eventsSubmitter.ts +35 -0
  139. package/src/sync/submitters/{impressionCountsSyncTask.ts → impressionCountsSubmitter.ts} +15 -15
  140. package/src/sync/submitters/{impressionsSyncTask.ts → impressionsSubmitter.ts} +12 -16
  141. package/src/sync/submitters/{submitterSyncTask.ts → submitter.ts} +33 -15
  142. package/src/sync/submitters/submitterManager.ts +14 -11
  143. package/src/sync/submitters/telemetrySubmitter.ts +143 -0
  144. package/src/sync/submitters/types.ts +123 -0
  145. package/src/sync/syncManagerOnline.ts +13 -7
  146. package/src/sync/types.ts +0 -15
  147. package/src/trackers/eventTracker.ts +7 -3
  148. package/src/trackers/impressionsTracker.ts +11 -3
  149. package/src/trackers/telemetryTracker.ts +63 -0
  150. package/src/trackers/types.ts +24 -0
  151. package/src/types.ts +35 -6
  152. package/src/utils/constants/index.ts +45 -0
  153. package/src/utils/inputValidation/apiKey.ts +2 -1
  154. package/src/utils/settingsValidation/index.ts +18 -4
  155. package/src/utils/settingsValidation/url.ts +4 -0
  156. package/src/utils/timeTracker/index.ts +1 -1
  157. package/src/utils/timeTracker/timer.ts +3 -3
  158. package/types/logger/constants.d.ts +1 -0
  159. package/types/sdkFactory/types.d.ts +29 -14
  160. package/types/services/splitApi.d.ts +2 -1
  161. package/types/services/types.d.ts +8 -5
  162. package/types/storages/AbstractSegmentsCacheSync.d.ts +7 -3
  163. package/types/storages/KeyBuilderSS.d.ts +3 -3
  164. package/types/storages/findLatencyIndex.d.ts +7 -1
  165. package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -0
  166. package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +2 -0
  167. package/types/storages/inMemory/SegmentsCacheInMemory.d.ts +1 -0
  168. package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -2
  169. package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +3 -3
  170. package/types/storages/pluggable/TelemetryCachePluggable.d.ts +2 -2
  171. package/types/storages/types.d.ts +71 -22
  172. package/types/sync/offline/syncManagerOffline.d.ts +3 -2
  173. package/types/sync/polling/pollingManagerCS.d.ts +2 -2
  174. package/types/sync/polling/pollingManagerSS.d.ts +2 -2
  175. package/types/sync/polling/syncTasks/splitsSyncTask.d.ts +1 -1
  176. package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -1
  177. package/types/sync/streaming/SSEHandler/NotificationKeeper.d.ts +2 -1
  178. package/types/sync/streaming/SSEHandler/index.d.ts +2 -1
  179. package/types/sync/streaming/pushManager.d.ts +2 -2
  180. package/types/sync/submitters/eventsSubmitter.d.ts +5 -0
  181. package/types/sync/submitters/impressionCountsSubmitter.d.ts +10 -0
  182. package/types/sync/submitters/impressionsSubmitter.d.ts +11 -0
  183. package/types/sync/submitters/submitter.d.ts +12 -0
  184. package/types/sync/submitters/submitterManager.d.ts +2 -2
  185. package/types/sync/submitters/telemetrySubmitter.d.ts +24 -0
  186. package/types/sync/submitters/telemetrySyncTask.d.ts +0 -27
  187. package/types/sync/submitters/types.d.ts +107 -0
  188. package/types/sync/syncManagerOnline.d.ts +3 -2
  189. package/types/sync/types.d.ts +0 -13
  190. package/types/trackers/eventTracker.d.ts +2 -2
  191. package/types/trackers/impressionsTracker.d.ts +2 -2
  192. package/types/trackers/telemetryTracker.d.ts +2 -3
  193. package/types/trackers/types.d.ts +22 -0
  194. package/types/types.d.ts +33 -4
  195. package/types/utils/constants/index.d.ts +37 -0
  196. package/types/utils/inputValidation/apiKey.d.ts +1 -0
  197. package/types/utils/settingsValidation/index.d.ts +40 -0
  198. package/types/utils/timeTracker/index.d.ts +1 -1
  199. package/types/utils/timeTracker/timer.d.ts +1 -1
  200. package/cjs/storages/inMemory/CountsCacheInMemory.js +0 -38
  201. package/cjs/storages/inMemory/LatenciesCacheInMemory.js +0 -43
  202. package/cjs/storages/inRedis/CountsCacheInRedis.js +0 -16
  203. package/cjs/storages/inRedis/LatenciesCacheInRedis.js +0 -18
  204. package/cjs/sync/submitters/eventsSyncTask.js +0 -44
  205. package/cjs/sync/submitters/metricsSyncTask.js +0 -31
  206. package/esm/storages/inMemory/CountsCacheInMemory.js +0 -35
  207. package/esm/storages/inMemory/LatenciesCacheInMemory.js +0 -40
  208. package/esm/storages/inRedis/CountsCacheInRedis.js +0 -13
  209. package/esm/storages/inRedis/LatenciesCacheInRedis.js +0 -15
  210. package/esm/sync/submitters/eventsSyncTask.js +0 -40
  211. package/esm/sync/submitters/metricsSyncTask.js +0 -26
  212. package/esm/sync/submitters/submitterSyncTask.js +0 -40
  213. package/src/storages/inMemory/CountsCacheInMemory.ts +0 -37
  214. package/src/storages/inMemory/LatenciesCacheInMemory.ts +0 -45
  215. package/src/storages/inRedis/CountsCacheInRedis.ts +0 -20
  216. package/src/storages/inRedis/LatenciesCacheInRedis.ts +0 -23
  217. package/src/sync/submitters/eventsSyncTask.ts +0 -57
  218. package/src/sync/submitters/metricsSyncTask.ts +0 -49
@@ -62,3 +62,126 @@ export type StoredEventWithMetadata = {
62
62
  /** Stored event */
63
63
  e: SplitIO.EventData
64
64
  }
65
+
66
+ /**
67
+ * Telemetry usage stats
68
+ */
69
+
70
+ export type QUEUED = 0;
71
+ export type DROPPED = 1;
72
+ export type DEDUPED = 2;
73
+ export type ImpressionDataType = QUEUED | DROPPED | DEDUPED
74
+ export type EventDataType = QUEUED | DROPPED;
75
+
76
+ export type SPLITS = 'sp';
77
+ export type IMPRESSIONS = 'im';
78
+ export type IMPRESSIONS_COUNT = 'ic';
79
+ export type EVENTS = 'ev';
80
+ export type TELEMETRY = 'te';
81
+ export type TOKEN = 'to';
82
+ export type SEGMENT = 'se';
83
+ export type MY_SEGMENT = 'ms';
84
+ export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
85
+
86
+ export type LastSync = Record<OperationType, number | undefined>
87
+ export type HttpErrors = Record<OperationType, { [statusCode: string]: number }>
88
+ export type HttpLatencies = Record<OperationType, Array<number>>
89
+
90
+ export type TREATMENT = 't';
91
+ export type TREATMENTS = 'ts';
92
+ export type TREATMENT_WITH_CONFIG = 'tc';
93
+ export type TREATMENTS_WITH_CONFIG = 'tcs';
94
+ export type TRACK = 'tr';
95
+ export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK;
96
+
97
+ export type MethodLatencies = Record<Method, Array<number>>;
98
+
99
+ export type MethodExceptions = Record<Method, number>;
100
+
101
+ export type CONNECTION_ESTABLISHED = 0;
102
+ export type OCCUPANCY_PRI = 10;
103
+ export type OCCUPANCY_SEC = 20;
104
+ export type STREAMING_STATUS = 30;
105
+ export type SSE_CONNECTION_ERROR = 40;
106
+ export type TOKEN_REFRESH = 50;
107
+ export type ABLY_ERROR = 60;
108
+ export type SYNC_MODE_UPDATE = 70;
109
+ export type StreamingEventType = CONNECTION_ESTABLISHED | OCCUPANCY_PRI | OCCUPANCY_SEC | STREAMING_STATUS | SSE_CONNECTION_ERROR | TOKEN_REFRESH | ABLY_ERROR | SYNC_MODE_UPDATE;
110
+
111
+ export type StreamingEvent = {
112
+ e: StreamingEventType, // eventType
113
+ d?: number, // eventData
114
+ t: number, // timestamp
115
+ }
116
+
117
+ // 'metrics/usage' JSON request body
118
+ export type TelemetryUsageStatsPayload = {
119
+ lS: LastSync, // lastSynchronization
120
+ mL: MethodLatencies, // clientMethodLatencies
121
+ mE: MethodExceptions, // methodExceptions
122
+ hE: HttpErrors, // httpErrors
123
+ hL: HttpLatencies, // httpLatencies
124
+ tR: number, // tokenRefreshes
125
+ aR: number, // authRejections
126
+ iQ: number, // impressionsQueued
127
+ iDe: number, // impressionsDeduped
128
+ iDr: number, // impressionsDropped
129
+ spC: number, // splitCount
130
+ seC: number, // segmentCount
131
+ skC: number, // segmentKeyCount
132
+ sL?: number, // sessionLengthMs
133
+ eQ: number, // eventsQueued
134
+ eD: number, // eventsDropped
135
+ sE: Array<StreamingEvent>, // streamingEvents
136
+ t?: Array<string>, // tags
137
+ }
138
+
139
+ /**
140
+ * Telemetry config stats
141
+ */
142
+
143
+ export type STANDALONE_ENUM = 0;
144
+ export type CONSUMER_ENUM = 1;
145
+ export type CONSUMER_PARTIAL_ENUM = 2;
146
+ export type OperationMode = STANDALONE_ENUM | CONSUMER_ENUM | CONSUMER_PARTIAL_ENUM
147
+
148
+ export type OPTIMIZED_ENUM = 0;
149
+ export type DEBUG_ENUM = 1;
150
+ export type ImpressionsMode = OPTIMIZED_ENUM | DEBUG_ENUM;
151
+
152
+ export type RefreshRates = {
153
+ sp: number, // splits
154
+ se: number, // mySegments
155
+ im: number, // impressions
156
+ ev: number, // events
157
+ te: number, // telemetry
158
+ }
159
+
160
+ export type UrlOverrides = {
161
+ s: boolean, // sdkUrl
162
+ e: boolean, // events
163
+ a: boolean, // auth
164
+ st: boolean, // stream
165
+ t: boolean, // telemetry
166
+ }
167
+
168
+ // 'metrics/config' JSON request body
169
+ export type TelemetryConfigStatsPayload = {
170
+ oM?: OperationMode, // operationMode
171
+ st: 'memory' | 'redis' | 'pluggable' | 'localstorage', // storage
172
+ sE: boolean, // streamingEnabled
173
+ rR: RefreshRates, // refreshRates
174
+ uO: UrlOverrides, // urlOverrides
175
+ iQ: number, // impressionsQueueSize
176
+ eQ: number, // eventsQueueSize
177
+ iM: ImpressionsMode, // impressionsMode
178
+ iL: boolean, // impressionsListenerEnabled
179
+ hP: boolean, // httpProxyDetected
180
+ aF: number, // activeFactories
181
+ rF: number, // redundantActiveFactories
182
+ tR: number, // timeUntilSDKReady
183
+ tC?: number, // timeUntilSDKReadyFromCache
184
+ nR: number, // SDKNotReadyUsage
185
+ t?: Array<string>, // tags
186
+ i?: Array<string>, // integrations
187
+ }
@@ -1,4 +1,4 @@
1
- import { ISyncManagerCS, ISyncManagerFactoryParams } from './types';
1
+ import { ISyncManagerCS } from './types';
2
2
  import { submitterManagerFactory } from './submitters/submitterManager';
3
3
  import { IReadinessManager } from '../readiness/types';
4
4
  import { IStorageSync } from '../storages/types';
@@ -7,6 +7,8 @@ import { IPollingManager, IPollingManagerCS } from './polling/types';
7
7
  import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
8
8
  import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
9
9
  import { isConsentGranted } from '../consent';
10
+ import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
11
+ import { ISdkFactoryContextSync } from '../sdkFactory/types';
10
12
 
11
13
  /**
12
14
  * Online SyncManager factory.
@@ -17,16 +19,16 @@ import { isConsentGranted } from '../consent';
17
19
  * @param pushManagerFactory optional to build a SyncManager with or without streaming support
18
20
  */
19
21
  export function syncManagerOnlineFactory(
20
- pollingManagerFactory?: (params: ISyncManagerFactoryParams) => IPollingManager,
21
- pushManagerFactory?: (params: ISyncManagerFactoryParams, pollingManager: IPollingManager) => IPushManager | undefined,
22
- ): (params: ISyncManagerFactoryParams) => ISyncManagerCS {
22
+ pollingManagerFactory?: (params: ISdkFactoryContextSync) => IPollingManager,
23
+ pushManagerFactory?: (params: ISdkFactoryContextSync, pollingManager: IPollingManager) => IPushManager | undefined,
24
+ ): (params: ISdkFactoryContextSync) => ISyncManagerCS {
23
25
 
24
26
  /**
25
27
  * SyncManager factory for modular SDK
26
28
  */
27
- return function (params: ISyncManagerFactoryParams): ISyncManagerCS {
29
+ return function (params: ISdkFactoryContextSync): ISyncManagerCS {
28
30
 
29
- const { settings, settings: { log, streamingEnabled } } = params;
31
+ const { settings, settings: { log, streamingEnabled }, telemetryTracker } = params;
30
32
 
31
33
  /** Polling Manager */
32
34
  const pollingManager = pollingManagerFactory && pollingManagerFactory(params);
@@ -48,13 +50,17 @@ export function syncManagerOnlineFactory(
48
50
  } else {
49
51
  log.info(SYNC_START_POLLING);
50
52
  pollingManager!.start();
53
+ telemetryTracker.streamingEvent(SYNC_MODE_UPDATE, POLLING);
51
54
  }
52
55
  }
53
56
 
54
57
  function stopPollingAndSyncAll() {
55
58
  log.info(SYNC_STOP_POLLING);
56
59
  // if polling, stop
57
- if (pollingManager!.isRunning()) pollingManager!.stop();
60
+ if (pollingManager!.isRunning()) {
61
+ pollingManager!.stop();
62
+ telemetryTracker.streamingEvent(SYNC_MODE_UPDATE, STREAMING);
63
+ }
58
64
 
59
65
  // fetch splits and segments. There is no need to catch this promise (it is always resolved)
60
66
  pollingManager!.syncAll();
package/src/sync/types.ts CHANGED
@@ -1,8 +1,5 @@
1
1
  import { IReadinessManager } from '../readiness/types';
2
- import { IPlatform } from '../sdkFactory/types';
3
- import { ISplitApi } from '../services/types';
4
2
  import { IStorageSync } from '../storages/types';
5
- import { ISettings } from '../types';
6
3
  import { IPollingManager } from './polling/types';
7
4
  import { IPushManager } from './streaming/types';
8
5
 
@@ -36,10 +33,6 @@ export interface ISyncTask<Input extends any[] = [], Output = any> extends ITask
36
33
  isExecuting(): boolean
37
34
  }
38
35
 
39
- export interface ITimeTracker {
40
- start(): () => void // start tracking time and return a function to call for stopping the tracking
41
- }
42
-
43
36
  /** SyncManager */
44
37
 
45
38
  export interface ISyncManager extends ITask {
@@ -52,11 +45,3 @@ export interface ISyncManager extends ITask {
52
45
  export interface ISyncManagerCS extends ISyncManager {
53
46
  shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync): ISyncManager | undefined
54
47
  }
55
-
56
- export interface ISyncManagerFactoryParams {
57
- settings: ISettings,
58
- readiness: IReadinessManager,
59
- storage: IStorageSync,
60
- splitApi: ISplitApi,
61
- platform: IPlatform
62
- }
@@ -1,10 +1,10 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { thenable } from '../utils/promise/thenable';
3
- import { IEventsCacheBase } from '../storages/types';
3
+ import { IEventsCacheBase, ITelemetryCacheAsync, ITelemetryCacheSync } from '../storages/types';
4
4
  import { IEventsHandler, IEventTracker } from './types';
5
5
  import { ISettings, SplitIO } from '../types';
6
6
  import { EVENTS_TRACKER_SUCCESS, ERROR_EVENTS_TRACKER } from '../logger/constants';
7
- import { CONSENT_DECLINED } from '../utils/constants';
7
+ import { CONSENT_DECLINED, DROPPED, QUEUED } from '../utils/constants';
8
8
  import { isStorageSync } from './impressionObserver/utils';
9
9
 
10
10
  /**
@@ -16,7 +16,8 @@ import { isStorageSync } from './impressionObserver/utils';
16
16
  export function eventTrackerFactory(
17
17
  settings: ISettings,
18
18
  eventsCache: IEventsCacheBase,
19
- integrationsManager?: IEventsHandler
19
+ integrationsManager?: IEventsHandler,
20
+ telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync
20
21
  ): IEventTracker {
21
22
 
22
23
  const log = settings.log;
@@ -57,6 +58,9 @@ export function eventTrackerFactory(
57
58
  if (thenable(tracked)) {
58
59
  return tracked.then(queueEventsCallback.bind(null, eventData));
59
60
  } else {
61
+ // Record when eventsCache is sync only (standalone mode)
62
+ // @TODO we are not dropping events on full queue yet, so `tracked` is always true ATM
63
+ if (telemetryCache) (telemetryCache as ITelemetryCacheSync).recordEventStats(tracked ? QUEUED : DROPPED, 1);
60
64
  return queueEventsCallback(eventData, tracked);
61
65
  }
62
66
  }
@@ -1,12 +1,12 @@
1
1
  import { objectAssign } from '../utils/lang/objectAssign';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { truncateTimeFrame } from '../utils/time';
4
- import { IImpressionCountsCacheSync, IImpressionsCacheBase } from '../storages/types';
4
+ import { IImpressionCountsCacheSync, IImpressionsCacheBase, ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
5
5
  import { IImpressionsHandler, IImpressionsTracker } from './types';
6
6
  import { SplitIO, ImpressionDTO, ISettings } from '../types';
7
7
  import { IImpressionObserver } from './impressionObserver/types';
8
8
  import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIONS_LISTENER } from '../logger/constants';
9
- import { CONSENT_DECLINED } from '../utils/constants';
9
+ import { CONSENT_DECLINED, DEDUPED, QUEUED } from '../utils/constants';
10
10
 
11
11
  /**
12
12
  * Impressions tracker stores impressions in cache and pass them to the listener and integrations manager if provided.
@@ -25,7 +25,8 @@ export function impressionsTrackerFactory(
25
25
  // if observer is provided, it implies `shouldAddPreviousTime` flag (i.e., if impressions previous time should be added or not)
26
26
  observer?: IImpressionObserver,
27
27
  // if countsCache is provided, it implies `isOptimized` flag (i.e., if impressions should be deduped or not)
28
- countsCache?: IImpressionCountsCacheSync
28
+ countsCache?: IImpressionCountsCacheSync,
29
+ telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync
29
30
  ): IImpressionsTracker {
30
31
 
31
32
  const { log, impressionListener, runtime: { ip, hostname }, version } = settings;
@@ -65,6 +66,13 @@ export function impressionsTrackerFactory(
65
66
  }).catch(err => {
66
67
  log.error(ERROR_IMPRESSIONS_TRACKER, [impressionsCount, err]);
67
68
  });
69
+ } else {
70
+ // Record when impressionsCache is sync only (standalone mode)
71
+ // @TODO we are not dropping impressions on full queue yet, so DROPPED stats are not recorded
72
+ if (telemetryCache) {
73
+ (telemetryCache as ITelemetryCacheSync).recordImpressionStats(QUEUED, impressionsToStore.length);
74
+ (telemetryCache as ITelemetryCacheSync).recordImpressionStats(DEDUPED, impressions.length - impressionsToStore.length);
75
+ }
68
76
  }
69
77
 
70
78
  // @TODO next block might be handled by the integration manager. In that case, the metadata object doesn't need to be passed in the constructor
@@ -0,0 +1,63 @@
1
+ import { ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
2
+ import { EXCEPTION, SDK_NOT_READY } from '../utils/labels';
3
+ import { ITelemetryTracker } from './types';
4
+ import { timer } from '../utils/timeTracker/timer';
5
+ import { TOKEN_REFRESH, AUTH_REJECTION } from '../utils/constants';
6
+
7
+ export function telemetryTrackerFactory(
8
+ telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync,
9
+ now?: () => number
10
+ ): ITelemetryTracker {
11
+
12
+ if (telemetryCache && now) {
13
+ const startTime = timer(now);
14
+
15
+ return {
16
+ trackEval(method) {
17
+ const evalTime = timer(now);
18
+
19
+ return (label) => {
20
+ switch (label) {
21
+ case EXCEPTION:
22
+ telemetryCache.recordException(method);
23
+ return; // Don't track latency on exceptions
24
+ case SDK_NOT_READY: // @ts-ignore ITelemetryCacheAsync doesn't implement the method
25
+ if (telemetryCache.recordNonReadyUsage) telemetryCache.recordNonReadyUsage();
26
+ }
27
+ telemetryCache.recordLatency(method, evalTime());
28
+ };
29
+ },
30
+ trackHttp(operation) {
31
+ const httpTime = timer(now);
32
+
33
+ return (error) => {
34
+ (telemetryCache as ITelemetryCacheSync).recordHttpLatency(operation, httpTime());
35
+ if (error && error.statusCode) (telemetryCache as ITelemetryCacheSync).recordHttpError(operation, error.statusCode);
36
+ else (telemetryCache as ITelemetryCacheSync).recordSuccessfulSync(operation, now());
37
+ };
38
+ },
39
+ sessionLength() { // @ts-ignore ITelemetryCacheAsync doesn't implement the method
40
+ if (telemetryCache.recordSessionLength) telemetryCache.recordSessionLength(startTime());
41
+ },
42
+ streamingEvent(e, d) {
43
+ if (e === AUTH_REJECTION) {
44
+ (telemetryCache as ITelemetryCacheSync).recordAuthRejections();
45
+ } else {
46
+ (telemetryCache as ITelemetryCacheSync).recordStreamingEvents({
47
+ e, d, t: now()
48
+ });
49
+ if (e === TOKEN_REFRESH) (telemetryCache as ITelemetryCacheSync).recordTokenRefreshes();
50
+ }
51
+ }
52
+ };
53
+
54
+ } else { // If there is not `telemetryCache` or `now` time tracker, return a no-op telemetry tracker
55
+ const noopTrack = () => () => { };
56
+ return {
57
+ trackEval: noopTrack,
58
+ trackHttp: noopTrack,
59
+ sessionLength: () => { },
60
+ streamingEvent: () => { },
61
+ };
62
+ }
63
+ }
@@ -1,5 +1,7 @@
1
1
  import { SplitIO, ImpressionDTO } from '../types';
2
+ import { StreamingEventType, Method, OperationType } from '../sync/submitters/types';
2
3
  import { IEventsCacheBase } from '../storages/types';
4
+ import { NetworkError } from '../services/types';
3
5
 
4
6
  /** Events tracker */
5
7
 
@@ -18,3 +20,25 @@ export interface IImpressionsHandler {
18
20
  export interface IImpressionsTracker {
19
21
  track(impressions: ImpressionDTO[], attributes?: SplitIO.Attributes): void
20
22
  }
23
+
24
+ /** Telemetry tracker */
25
+ export type AUTH_REJECTION = 80;
26
+
27
+ export interface ITelemetryTracker {
28
+ /**
29
+ * Creates a telemetry evaluator tracker, to record Latencies, Exceptions and NonReadyUsage of client operations (getTreatments and track method calls)
30
+ */
31
+ trackEval(method: Method): (label?: string) => void
32
+ /**
33
+ * Creates a telemetry runtime tracker, to record Latencies and Exceptions of HTTP requests
34
+ */
35
+ trackHttp(method: OperationType): (error?: NetworkError) => void
36
+ /**
37
+ * Records session length
38
+ */
39
+ sessionLength(): void
40
+ /**
41
+ * Records streaming event
42
+ */
43
+ streamingEvent(e: StreamingEventType | AUTH_REJECTION, d?: number): void
44
+ }
package/src/types.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { ISplitFiltersValidation } from './dtos/types';
2
2
  import { IIntegration, IIntegrationFactoryParams } from './integrations/types';
3
3
  import { ILogger } from './logger/types';
4
+ import { ISdkFactoryContext } from './sdkFactory/types';
4
5
  /* eslint-disable no-use-before-define */
5
6
 
6
7
  import { IStorageFactoryParams, IStorageSync, IStorageAsync, IStorageSyncFactory, IStorageAsyncFactory } from './storages/types';
7
- import { ISyncManagerFactoryParams, ISyncManagerCS } from './sync/types';
8
+ import { ISyncManagerCS } from './sync/types';
8
9
 
9
10
  /**
10
11
  * Reduced version of NodeJS.EventEmitter interface with the minimal methods used by the SDK
@@ -79,7 +80,11 @@ export interface ISettings {
79
80
  featuresRefreshRate: number,
80
81
  impressionsRefreshRate: number,
81
82
  impressionsQueueSize: number,
82
- metricsRefreshRate: number,
83
+ /**
84
+ * @deprecated
85
+ */
86
+ metricsRefreshRate?: number,
87
+ telemetryRefreshRate: number,
83
88
  segmentsRefreshRate: number,
84
89
  offlineRefreshRate: number,
85
90
  eventsPushRate: number,
@@ -93,12 +98,16 @@ export interface ISettings {
93
98
  eventsFirstPushWindow: number
94
99
  },
95
100
  readonly storage: IStorageSyncFactory | IStorageAsyncFactory,
96
- readonly integrations?: Array<(params: IIntegrationFactoryParams) => IIntegration | void>,
101
+ readonly integrations: Array<{
102
+ readonly type: string,
103
+ (params: IIntegrationFactoryParams): IIntegration | void
104
+ }>,
97
105
  readonly urls: {
98
106
  events: string,
99
107
  sdk: string,
100
108
  auth: string,
101
- streaming: string
109
+ streaming: string,
110
+ telemetry: string
102
111
  },
103
112
  readonly debug: boolean | LogLevel | ILogger,
104
113
  readonly version: string,
@@ -273,8 +282,15 @@ interface INodeBasicSettings extends ISharedSettings {
273
282
  * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
274
283
  * @property {number} metricsRefreshRate
275
284
  * @default 120
285
+ * @deprecated This parameter is ignored now.
276
286
  */
277
287
  metricsRefreshRate?: number,
288
+ /**
289
+ * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
290
+ * @property {number} telemetryRefreshRate
291
+ * @default 3600
292
+ */
293
+ telemetryRefreshRate?: number,
278
294
  /**
279
295
  * The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds.
280
296
  * @property {number} segmentsRefreshRate
@@ -607,7 +623,7 @@ export namespace SplitIO {
607
623
  */
608
624
  export type LocalhostFactory = {
609
625
  type: 'LocalhostFromObject' | 'LocalhostFromFile'
610
- (params: ISyncManagerFactoryParams): ISyncManagerCS
626
+ (params: ISdkFactoryContext): ISyncManagerCS
611
627
  }
612
628
  /**
613
629
  * Impression listener interface. This is the interface that needs to be implemented
@@ -664,7 +680,13 @@ export namespace SplitIO {
664
680
  * @property {string} streaming
665
681
  * @default 'https://streaming.split.io'
666
682
  */
667
- streaming?: string
683
+ streaming?: string,
684
+ /**
685
+ * String property to override the base URL where the SDK will post telemetry data.
686
+ * @property {string} telemetry
687
+ * @default 'https://telemetry.split.io'
688
+ */
689
+ telemetry?: string
668
690
  };
669
691
  /**
670
692
  * SplitFilter type.
@@ -794,8 +816,15 @@ export namespace SplitIO {
794
816
  * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
795
817
  * @property {number} metricsRefreshRate
796
818
  * @default 120
819
+ * @deprecated This parameter is ignored now.
797
820
  */
798
821
  metricsRefreshRate?: number,
822
+ /**
823
+ * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
824
+ * @property {number} telemetryRefreshRate
825
+ * @default 3600
826
+ */
827
+ telemetryRefreshRate?: number,
799
828
  /**
800
829
  * The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds.
801
830
  * @property {number} segmentsRefreshRate
@@ -37,3 +37,48 @@ export const STORAGE_PLUGGABLE: StorageType = 'PLUGGABLE';
37
37
  export const CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
38
38
  export const CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
39
39
  export const CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
40
+
41
+ // Telemetry
42
+ export const QUEUED = 0;
43
+ export const DROPPED = 1;
44
+ export const DEDUPED = 2;
45
+
46
+ export const STANDALONE_ENUM = 0;
47
+ export const CONSUMER_ENUM = 1;
48
+ export const CONSUMER_PARTIAL_ENUM = 2;
49
+
50
+ export const OPTIMIZED_ENUM = 0;
51
+ export const DEBUG_ENUM = 1;
52
+
53
+ export const SPLITS = 'sp';
54
+ export const IMPRESSIONS = 'im';
55
+ export const IMPRESSIONS_COUNT = 'ic';
56
+ export const EVENTS = 'ev';
57
+ export const TELEMETRY = 'te';
58
+ export const TOKEN = 'to';
59
+ export const SEGMENT = 'se';
60
+ export const MY_SEGMENT = 'ms';
61
+
62
+ export const TREATMENT = 't';
63
+ export const TREATMENTS = 'ts';
64
+ export const TREATMENT_WITH_CONFIG = 'tc';
65
+ export const TREATMENTS_WITH_CONFIG = 'tcs';
66
+ export const TRACK = 'tr';
67
+
68
+ export const CONNECTION_ESTABLISHED = 0;
69
+ export const OCCUPANCY_PRI = 10;
70
+ export const OCCUPANCY_SEC = 20;
71
+ export const STREAMING_STATUS = 30;
72
+ export const SSE_CONNECTION_ERROR = 40;
73
+ export const TOKEN_REFRESH = 50;
74
+ export const ABLY_ERROR = 60;
75
+ export const SYNC_MODE_UPDATE = 70;
76
+ export const AUTH_REJECTION = 80;
77
+
78
+ export const STREAMING = 0;
79
+ export const POLLING = 1;
80
+ export const REQUESTED = 0;
81
+ export const NON_REQUESTED = 1;
82
+ export const DISABLED = 0;
83
+ export const ENABLED = 1;
84
+ export const PAUSED = 2;
@@ -21,7 +21,8 @@ export function validateApiKey(log: ILogger, maybeApiKey: any): string | false {
21
21
  return apiKey;
22
22
  }
23
23
 
24
- const usedKeysMap: Record<string, number> = {};
24
+ // Exported for telemetry
25
+ export const usedKeysMap: Record<string, number> = {};
25
26
 
26
27
  /** validates the given api key and also warns if it is in use */
27
28
  export function validateAndTrackApiKey(log: ILogger, maybeApiKey: any): string | false {
@@ -7,8 +7,10 @@ import { ISettingsValidationParams } from './types';
7
7
  import { ISettings } from '../../types';
8
8
  import { validateKey } from '../inputValidation/key';
9
9
  import { validateTrafficType } from '../inputValidation/trafficType';
10
+ import { ERROR_MIN_CONFIG_PARAM } from '../../logger/constants';
10
11
 
11
- const base = {
12
+ // Exported for telemetry
13
+ export const base = {
12
14
  // Define which kind of object you want to retrieve from SplitFactory
13
15
  mode: STANDALONE_MODE,
14
16
 
@@ -30,8 +32,8 @@ const base = {
30
32
  featuresRefreshRate: 30,
31
33
  // fetch segments updates each 60 sec
32
34
  segmentsRefreshRate: 60,
33
- // publish metrics each 120 sec
34
- metricsRefreshRate: 120,
35
+ // publish telemetry stats each 3600 secs (1 hour)
36
+ telemetryRefreshRate: 3600,
35
37
  // publish evaluations each 60 sec
36
38
  impressionsRefreshRate: 60,
37
39
  // fetch offline changes each 15 sec
@@ -55,6 +57,8 @@ const base = {
55
57
  auth: 'https://auth.split.io/api',
56
58
  // Streaming Server
57
59
  streaming: 'https://streaming.split.io',
60
+ // Telemetry Server
61
+ telemetry: 'https://telemetry.split.io',
58
62
  },
59
63
 
60
64
  // Defines which kind of storage we should instanciate.
@@ -109,14 +113,24 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
109
113
  const log = logger(withDefaults); // @ts-ignore, modify readonly prop
110
114
  withDefaults.log = log;
111
115
 
116
+ function validateMinValue(paramName: string, actualValue: number, minValue: number) {
117
+ if (actualValue >= minValue) return actualValue;
118
+ // actualValue is not a number or is lower than minValue
119
+ log.error(ERROR_MIN_CONFIG_PARAM, [paramName, minValue]);
120
+ return minValue;
121
+ }
122
+
112
123
  // Scheduler periods
113
124
  const { scheduler, startup } = withDefaults;
114
125
  scheduler.featuresRefreshRate = fromSecondsToMillis(scheduler.featuresRefreshRate);
115
126
  scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
116
- scheduler.metricsRefreshRate = fromSecondsToMillis(scheduler.metricsRefreshRate);
117
127
  scheduler.impressionsRefreshRate = fromSecondsToMillis(scheduler.impressionsRefreshRate);
118
128
  scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
119
129
  scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
130
+ scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
131
+
132
+ // Log deprecation for old telemetry param
133
+ if (scheduler.metricsRefreshRate) log.warn('`metricsRefreshRate` will be deprecated soon. For configuring telemetry rates, update `telemetryRefreshRate` value in configs');
120
134
 
121
135
  // Startup periods
122
136
  startup.requestTimeoutBeforeReady = fromSecondsToMillis(startup.requestTimeoutBeforeReady);
@@ -1,5 +1,6 @@
1
1
  import { ISettings } from '../../types';
2
2
 
3
+ const telemetryEndpointMatcher = /^\/metrics\/(config|usage)/;
3
4
  const eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
4
5
  const authEndpointMatcher = /^\/v2\/auth/;
5
6
  const streamingEndpointMatcher = /^\/(sse|event-stream)/;
@@ -13,6 +14,9 @@ const streamingEndpointMatcher = /^\/(sse|event-stream)/;
13
14
  * @return complete url
14
15
  */
15
16
  export function url(settings: ISettings, target: string) {
17
+ if (telemetryEndpointMatcher.test(target)) {
18
+ return `${settings.urls.telemetry}${target}`;
19
+ }
16
20
  if (eventsEndpointMatcher.test(target)) {
17
21
  return `${settings.urls.events}${target}`;
18
22
  }
@@ -148,7 +148,7 @@ export const TrackerAPI = {
148
148
  * @param {Promise} promise - (optional) The promise we are tracking.
149
149
  * @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
150
150
  */
151
- start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector>, promise?: Promise<IResponse>, now?: () => number): Promise<IResponse> | (() => number) {
151
+ start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector>, promise?: Promise<IResponse>, now: () => number = Date.now): Promise<IResponse> | (() => number) {
152
152
  const taskUniqueId = uniqueId();
153
153
  const taskCollector = getCollectorForTask(task, collectors);
154
154
  let result;
@@ -1,7 +1,7 @@
1
- export function timer(now?: () => number) {
2
- const st = now ? now() : Date.now();
1
+ export function timer(now: () => number) {
2
+ const st = now();
3
3
 
4
4
  return function stop() {
5
- return Math.round(now ? now() : Date.now() - st);
5
+ return Math.round(now() - st);
6
6
  };
7
7
  }
@@ -120,6 +120,7 @@ export declare const ERROR_HTTP = 322;
120
120
  export declare const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
121
121
  export declare const ERROR_STORAGE_INVALID = 324;
122
122
  export declare const ERROR_NOT_BOOLEAN = 325;
123
+ export declare const ERROR_MIN_CONFIG_PARAM = 326;
123
124
  export declare const LOG_PREFIX_SETTINGS = "settings";
124
125
  export declare const LOG_PREFIX_INSTANTIATION = "Factory instantiation";
125
126
  export declare const LOG_PREFIX_ENGINE = "engine";