comprodls-sdk 2.89.0 → 2.90.0-qa

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 (41) hide show
  1. package/README.md +1 -137
  2. package/dist/comprodls-sdk.js +5937 -8432
  3. package/dist/comprodls-sdk.min.js +15 -1
  4. package/lib/comprodls.js +39 -57
  5. package/lib/config/index.js +171 -199
  6. package/lib/helpers/index.js +3 -2
  7. package/lib/helpers/lib/api/converter.js +1 -2
  8. package/lib/helpers/lib/api/index.js +19 -94
  9. package/lib/helpers/lib/errors.js +73 -80
  10. package/lib/helpers/lib/requestLayer.js +154 -0
  11. package/lib/helpers/lib/validator.js +65 -52
  12. package/lib/open_access/index.js +48 -53
  13. package/lib/services/analytics/index.js +286 -1014
  14. package/lib/services/attempts/index.js +38 -88
  15. package/lib/services/auth/index.js +238 -896
  16. package/lib/services/authextn/index.js +50 -150
  17. package/lib/services/datasyncmanager/index.js +10 -45
  18. package/lib/services/drive/index.js +20 -83
  19. package/lib/services/integrations/index.js +51 -126
  20. package/lib/services/invitations/index.js +20 -61
  21. package/lib/services/product/index.js +74 -85
  22. package/lib/services/pub/index.js +159 -234
  23. package/lib/services/pushX/index.js +29 -33
  24. package/lib/services/pushX/pubnubClientWrapper.js +398 -398
  25. package/lib/services/rules/index.js +14 -67
  26. package/lib/services/spaces/index.js +106 -294
  27. package/lib/services/spacesextn/index.js +4 -24
  28. package/lib/services/superuser/index.js +21 -36
  29. package/lib/services/taxonomy/index.js +27 -57
  30. package/lib/services/workflows/index.js +37 -98
  31. package/lib/services/xapi/index.js +6 -125
  32. package/lib/token/index.js +73 -67
  33. package/lib/token/validations.js +45 -48
  34. package/package.json +1 -2
  35. package/lib/helpers/lib/api/validations.js +0 -73
  36. package/lib/helpers/lib/utils.js +0 -24
  37. package/lib/services/activity/activity.js +0 -209
  38. package/lib/services/activity/attempt.js +0 -431
  39. package/lib/services/activity/index.js +0 -28
  40. package/lib/services/auth/classProduct.js +0 -37
  41. package/lib/services/collab/index.js +0 -468
@@ -1,6 +1,6 @@
1
- var pubNub = require("pubnub");
1
+ var pubNub = require('pubnub');
2
2
  var request = require('superagent');
3
- var EventEmitter = require("events").EventEmitter;
3
+ var EventEmitter = require('events').EventEmitter;
4
4
  var helpers = require('../../helpers');
5
5
 
6
6
  var PUSHXError = helpers.errors.PUSHXError;
@@ -13,426 +13,426 @@ var CHANNEL_DELIMITER = '$';
13
13
  * implementation details - allowing future switch (to a different Saas provider).
14
14
  */
15
15
  module.exports = function () {
16
- "use strict";
17
-
18
- /** ====== MODULE GLOBALS */
19
- var _pubnubClient; //SAAS provider client SDK (PubNub).
20
- var _eventEmitter = new EventEmitter();
21
- var _userOptions;
22
- var _globalSubscription = [];
23
- var _globalSubscriptionStatus = {};
24
- var bStatusSubscribed = false;
25
- /** ID of the setTimeout - used for Polling events when PubNub fails */
26
- var _setTimeoutIDForPolling;
27
- /** Timestamp from when the events need to be fetched */
28
- var _startTimestampForPolling;
29
- /** Counter for polling */
30
- var _pollingCounter;
31
- var bPollingInitiated = false;
32
-
33
- /** ###### END OF MODULE GLOBALS */
34
-
35
- /** ====== UTILITY FUNCTIONS */
36
-
37
-
38
- /**
39
- * Call this function to make a new client adaptor.
40
- This adapter exposes functions to send message, update user state etc.
41
- * @return (object) : client adapter.
42
- */
43
- var _constructClientAdaptor = function () {
44
- //Returning the adaptor (Plain Javascript object)
45
- return {
46
- "on": function (channelObj, handler) {
47
- // If PubNub fails, we will fetch the events from this timestamp
48
- _startTimestampForPolling = Date.now();
49
-
50
- var pubNubChannel;
51
- var channelContext = [];
52
-
53
- if((channelObj.orgid || channelObj.userid) || channelObj.accountid ||
54
- channelObj.productid || channelObj.classid)
55
- {
56
- if(channelObj.accountid) { channelContext.push('a-' + channelObj.accountid); }
57
- else {
58
- if(channelObj.orgid) { channelContext.push('o-' + channelObj.orgid); }
59
- if(channelObj.userid) { channelContext.push('u-' + channelObj.userid); }
60
- if(channelObj.productid) { channelContext.push('p-' + channelObj.productid); }
61
- if(channelObj.classid) { channelContext.push('c-' + channelObj.classid); }
62
- }
63
- pubNubChannel = channelContext.join(CHANNEL_DELIMITER) + CHANNEL_DELIMITER +
64
- channelObj.channel;
65
- if(!_globalSubscription.includes(pubNubChannel)) {
66
- _globalSubscription.push(pubNubChannel);
67
- _globalSubscriptionStatus[pubNubChannel] = {
68
- status: 'pending'
69
- };
70
- _eventEmitter.on(pubNubChannel, handler);
71
- _subscribeToPubNubChannels(pubNubChannel);
72
- }
73
- }
74
- else if(channelObj.channel === 'pushx_status' && ! bStatusSubscribed) {
75
- _eventEmitter.on(channelObj.channel, handler);
76
- bStatusSubscribed = true;
77
- }
78
-
79
- // Clean up the old events
80
- _checkOldBubbledEvents();
81
- },
82
- "getMySubscriptionStatus": __getMySubscriptionStatus
83
- };
84
- };
85
-
86
- var _translatePubnubMessage = function (pubNubEventData) {
87
- var subscribedChannel = pubNubEventData.subscribedChannel;
88
- var message = pubNubEventData.message;
89
- _eventEmitter.emit(subscribedChannel, message);
90
- };
91
-
92
- var _translatePubnubStatus = function(status, options) {
93
- var channels = [], error, successObj;
94
-
95
- // If polling has been initiated, ignore all punnub status
96
- if (bPollingInitiated) return;
97
-
98
- switch (status.category) {
99
- case "PNConnectedCategory":
100
- if(status.operation === "PNSubscribeOperation") {
101
- channels = status.subscribedChannels;
102
- for(var i in channels) {
103
- if(_globalSubscriptionStatus[channels[i]]) {
104
- _globalSubscriptionStatus[channels[i]].status = 'subscribed';
105
- }
106
- }
107
- successObj = {
108
- category: 'PUSHX',
109
- type: 'CHANNEL_SUBSCRIPTION',
110
- status: 'SUCCESS',
111
- message: 'Success: Subscribed successfully.',
112
- httpcode: 200,
113
- data: {
114
- payload: {
115
- channels: status.subscribedChannels
116
- },
117
- message: 'Success: Subscribed successfully.'
118
- }
119
- };
120
- _eventEmitter.emit('pushx_status', successObj);
121
- }
122
- break;
123
- case "PNAccessDeniedCategory":
124
- if(status.operation === "PNSubscribeOperation") {
125
- var errorText = status.errorData.response && status.errorData.response.text;
126
- var errorJSON = errorText ? JSON.parse(errorText) : undefined;
127
- var errorData = {
128
- payload: errorJSON && errorJSON.payload || status.errorData.payload,
129
- message: 'Forbidden: Subscription failed.',
130
- errorDetails: {
131
- operation: status.operation,
132
- category: status.category,
133
- statusCode: status.statusCode
134
- }
135
- };
136
- channels = errorData.payload.channels;
137
- for(var j in channels) {
138
- if(_globalSubscriptionStatus[channels[j]]) {
139
- _globalSubscriptionStatus[channels[j]].status = 'error';
140
- _globalSubscriptionStatus[channels[j]].error = error;
141
- }
142
- }
143
- error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, errorData);
144
- _eventEmitter.emit('pushx_status', error);
145
- }
146
- break;
147
- case "PNBadRequestCategory":
148
- case "PNNetworkDownCategory":
149
- case "PNNetworkUpCategory":
150
- error = {
151
- message: "PushX Error", status: status.statusCode,
152
- pushXError: status
153
- };
154
- error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
155
- _eventEmitter.emit('pushx_status', error);
156
- break;
157
- case "PNNetworkIssuesCategory":
158
- if(status.operation === 'PNSubscribeOperation') {
159
- if(!options.accountId || !_userOptions.pollingEndpoint) {
160
- error = {
161
- message: "Polling initiation error: Missing mandatory parameters to initiate polling operation - [accountId, pollingEndpoint]",
162
- status: status.statusCode
163
- };
164
- error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
165
- _eventEmitter.emit('pushx_status', error);
166
- break;
167
- }
168
- else {
169
- /**
170
- * Handle network issue category status for 'subscription' opreration
171
- * Start the events polling here.
172
- *
173
- * The wrapper supports multiple channels, but the APP currently uses a single channel only.
174
- * Polling will also limited to a single channel.
175
- */
176
- _pollingCounter = 0;
177
- _pollForEvents();
178
- bPollingInitiated = true;
179
- }
180
- }
181
- else {
182
- // Handle network issue category status for other operations like 'unsubscription'
183
- }
184
- break;
185
- case "PNReconnectedCategory":
186
- // Handle reconnected category status.
187
- break;
188
- default:
189
- // Emit error for other status-category received from pubnub
190
- error = {
191
- message: "PushX Error: unexpected error",
192
- status: status.statusCode,
193
- pushXError: status
194
- };
195
- error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
196
- _eventEmitter.emit('pushx_status', error);
197
- break;
198
- }
199
- };
200
-
201
- var __getMySubscriptionStatus = function() {
202
- return JSON.parse(JSON.stringify(_globalSubscriptionStatus));
203
- };
204
-
205
- /**
206
- * Sets up necessary subscriptions (Pub/Sub) to PUSH channels. To a large extent, subscriptions are
207
- * driven the student's (instructor's) roster.
208
- * @param {object} groups - Roster information, provided during initialization, wrapper.setup().
209
- */
210
- var _subscribeToPubNubChannels = function (channel) {
211
- _pubnubClient.subscribe({ // Calling Pubnub SDK
212
- "channels": [channel]
213
- });
16
+ 'use strict';
17
+
18
+ /** ====== MODULE GLOBALS */
19
+ var _pubnubClient; //SAAS provider client SDK (PubNub).
20
+ var _eventEmitter = new EventEmitter();
21
+ var _userOptions;
22
+ var _globalSubscription = [];
23
+ var _globalSubscriptionStatus = {};
24
+ var bStatusSubscribed = false;
25
+ /** ID of the setTimeout - used for Polling events when PubNub fails */
26
+ var _setTimeoutIDForPolling;
27
+ /** Timestamp from when the events need to be fetched */
28
+ var _startTimestampForPolling;
29
+ /** Counter for polling */
30
+ var _pollingCounter;
31
+ var bPollingInitiated = false;
32
+
33
+ /** ###### END OF MODULE GLOBALS */
34
+
35
+ /** ====== UTILITY FUNCTIONS */
36
+
37
+
38
+ /**
39
+ * Call this function to make a new client adaptor.
40
+ This adapter exposes functions to send message, update user state etc.
41
+ * @return (object) : client adapter.
42
+ */
43
+ var _constructClientAdaptor = function () {
44
+ //Returning the adaptor (Plain Javascript object)
45
+ return {
46
+ 'on': function (channelObj, handler) {
47
+ // If PubNub fails, we will fetch the events from this timestamp
48
+ _startTimestampForPolling = Date.now();
49
+
50
+ var pubNubChannel;
51
+ var channelContext = [];
52
+
53
+ if((channelObj.orgid || channelObj.userid) || channelObj.accountid ||
54
+ channelObj.productid || channelObj.classid)
55
+ {
56
+ if(channelObj.accountid) { channelContext.push('a-' + channelObj.accountid); }
57
+ else {
58
+ if(channelObj.orgid) { channelContext.push('o-' + channelObj.orgid); }
59
+ if(channelObj.userid) { channelContext.push('u-' + channelObj.userid); }
60
+ if(channelObj.productid) { channelContext.push('p-' + channelObj.productid); }
61
+ if(channelObj.classid) { channelContext.push('c-' + channelObj.classid); }
62
+ }
63
+ pubNubChannel = channelContext.join(CHANNEL_DELIMITER) + CHANNEL_DELIMITER +
64
+ channelObj.channel;
65
+ if(!_globalSubscription.includes(pubNubChannel)) {
66
+ _globalSubscription.push(pubNubChannel);
67
+ _globalSubscriptionStatus[pubNubChannel] = {
68
+ status: 'pending'
69
+ };
70
+ _eventEmitter.on(pubNubChannel, handler);
71
+ _subscribeToPubNubChannels(pubNubChannel);
72
+ }
73
+ }
74
+ else if(channelObj.channel === 'pushx_status' && ! bStatusSubscribed) {
75
+ _eventEmitter.on(channelObj.channel, handler);
76
+ bStatusSubscribed = true;
77
+ }
78
+
79
+ // Clean up the old events
80
+ _checkOldBubbledEvents();
81
+ },
82
+ 'getMySubscriptionStatus': __getMySubscriptionStatus
214
83
  };
215
-
216
- /** ###### END OF UTILITY FUNCTIONS ############ */
217
-
218
- /** ====== Client Wrapper Member functions ==> Mapped to Public Methods */
219
-
220
- /**
221
- * Initializes the library, and established a connection with the Saas/PUSH provider.
222
- * Setup should be called only once i.e. ONE CONNECTION (on a page/tab) is allowed
223
- * at a time. If called again, it will throw an error (failure callback).
224
- *
225
- * @param {object} userOptions - User auth key and pubnub credentials
226
- * @returns PROMISE.
227
- */
228
- var __setup = function (userOptions) {
229
-
230
- var pubnubConfig = userOptions.pubnub;
231
- pubnubConfig.uuid = userOptions.userid;
232
- var accountId = userOptions.accountid;
233
- var token = userOptions.token;
234
-
235
- if (!_pubnubClient && pubnubConfig) {
236
- _pubnubClient = new pubNub(pubnubConfig); //Connect with PubNub SDK
237
- _pubnubClient.setToken(token);
238
- processSetup();
239
- } else {
240
- return new Error('Already Initialized');
84
+ };
85
+
86
+ var _translatePubnubMessage = function (pubNubEventData) {
87
+ var subscribedChannel = pubNubEventData.subscribedChannel;
88
+ var message = pubNubEventData.message;
89
+ _eventEmitter.emit(subscribedChannel, message);
90
+ };
91
+
92
+ var _translatePubnubStatus = function(status, options) {
93
+ var channels = [], error, successObj;
94
+
95
+ // If polling has been initiated, ignore all punnub status
96
+ if (bPollingInitiated) return;
97
+
98
+ switch (status.category) {
99
+ case 'PNConnectedCategory':
100
+ if(status.operation === 'PNSubscribeOperation') {
101
+ channels = status.subscribedChannels;
102
+ for(var i in channels) {
103
+ if(_globalSubscriptionStatus[channels[i]]) {
104
+ _globalSubscriptionStatus[channels[i]].status = 'subscribed';
105
+ }
106
+ }
107
+ successObj = {
108
+ category: 'PUSHX',
109
+ type: 'CHANNEL_SUBSCRIPTION',
110
+ status: 'SUCCESS',
111
+ message: 'Success: Subscribed successfully.',
112
+ httpcode: 200,
113
+ data: {
114
+ payload: {
115
+ channels: status.subscribedChannels
116
+ },
117
+ message: 'Success: Subscribed successfully.'
118
+ }
119
+ };
120
+ _eventEmitter.emit('pushx_status', successObj);
241
121
  }
242
-
243
- /**
244
- * SYNC Function
245
- */
246
- function processSetup() {
247
- _userOptions = userOptions;
248
- _pubnubClient.addListener({ //Setup Listeners (events will shows up after subscription)
249
- "message": function (data) {
250
- _translatePubnubMessage(data);
251
- },
252
- "status": function (status) {
253
- var statusOptions = { accountId: accountId };
254
- _translatePubnubStatus(status, statusOptions);
255
- }
256
- });
122
+ break;
123
+ case 'PNAccessDeniedCategory':
124
+ if(status.operation === 'PNSubscribeOperation') {
125
+ var errorText = status.errorData.response && status.errorData.response.text;
126
+ var errorJSON = errorText ? JSON.parse(errorText) : undefined;
127
+ var errorData = {
128
+ payload: errorJSON && errorJSON.payload || status.errorData.payload,
129
+ message: 'Forbidden: Subscription failed.',
130
+ errorDetails: {
131
+ operation: status.operation,
132
+ category: status.category,
133
+ statusCode: status.statusCode
134
+ }
135
+ };
136
+ channels = errorData.payload.channels;
137
+ for(var j in channels) {
138
+ if(_globalSubscriptionStatus[channels[j]]) {
139
+ _globalSubscriptionStatus[channels[j]].status = 'error';
140
+ _globalSubscriptionStatus[channels[j]].error = error;
141
+ }
142
+ }
143
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, errorData);
144
+ _eventEmitter.emit('pushx_status', error);
257
145
  }
258
- return _constructClientAdaptor();
259
- }; //End of _setup()
260
-
261
- var __cleanup = function () {
262
- if (_pubnubClient) { //Skip cleanup if setup() was not called.
263
- _pubnubClient.unsubscribeAll();
264
- _pubnubClient.stop();
265
- _globalSubscription = [];
266
- bStatusSubscribed = false;
267
- _globalSubscriptionStatus = {};
268
- bPollingInitiated = false;
146
+ break;
147
+ case 'PNBadRequestCategory':
148
+ case 'PNNetworkDownCategory':
149
+ case 'PNNetworkUpCategory':
150
+ error = {
151
+ message: 'PushX Error', status: status.statusCode,
152
+ pushXError: status
153
+ };
154
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
155
+ _eventEmitter.emit('pushx_status', error);
156
+ break;
157
+ case 'PNNetworkIssuesCategory':
158
+ if(status.operation === 'PNSubscribeOperation') {
159
+ if(!options.accountId || !_userOptions.pollingEndpoint) {
160
+ error = {
161
+ message: 'Polling initiation error: Missing mandatory parameters to initiate polling operation - [accountId, pollingEndpoint]',
162
+ status: status.statusCode
163
+ };
164
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
165
+ _eventEmitter.emit('pushx_status', error);
166
+ break;
167
+ }
168
+ else {
169
+ /**
170
+ * Handle network issue category status for 'subscription' opreration
171
+ * Start the events polling here.
172
+ *
173
+ * The wrapper supports multiple channels, but the APP currently uses a single channel only.
174
+ * Polling will also limited to a single channel.
175
+ */
176
+ _pollingCounter = 0;
177
+ _pollForEvents();
178
+ bPollingInitiated = true;
179
+ }
269
180
  }
270
- _pubnubClient = undefined;
271
-
272
- // Clear the Polling
273
- if (_setTimeoutIDForPolling) {
274
- clearTimeout(_setTimeoutIDForPolling);
275
- // Setting the start time to now to clear the old events
276
- _startTimestampForPolling = Date.now();
277
- _checkOldBubbledEvents();
278
- _setTimeoutIDForPolling = undefined;
279
- _pollingCounter = undefined;
280
- _startTimestampForPolling = undefined;
181
+ else {
182
+ // Handle network issue category status for other operations like 'unsubscription'
281
183
  }
282
- };
184
+ break;
185
+ case 'PNReconnectedCategory':
186
+ // Handle reconnected category status.
187
+ break;
188
+ default:
189
+ // Emit error for other status-category received from pubnub
190
+ error = {
191
+ message: 'PushX Error: unexpected error',
192
+ status: status.statusCode,
193
+ pushXError: status
194
+ };
195
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
196
+ _eventEmitter.emit('pushx_status', error);
197
+ break;
198
+ }
199
+ };
200
+
201
+ var __getMySubscriptionStatus = function() {
202
+ return JSON.parse(JSON.stringify(_globalSubscriptionStatus));
203
+ };
204
+
205
+ /**
206
+ * Sets up necessary subscriptions (Pub/Sub) to PUSH channels. To a large extent, subscriptions are
207
+ * driven the student's (instructor's) roster.
208
+ * @param {object} groups - Roster information, provided during initialization, wrapper.setup().
209
+ */
210
+ var _subscribeToPubNubChannels = function (channel) {
211
+ _pubnubClient.subscribe({ // Calling Pubnub SDK
212
+ 'channels': [channel]
213
+ });
214
+ };
215
+
216
+ /** ###### END OF UTILITY FUNCTIONS ############ */
217
+
218
+ /** ====== Client Wrapper Member functions ==> Mapped to Public Methods */
219
+
220
+ /**
221
+ * Initializes the library, and established a connection with the Saas/PUSH provider.
222
+ * Setup should be called only once i.e. ONE CONNECTION (on a page/tab) is allowed
223
+ * at a time. If called again, it will throw an error (failure callback).
224
+ *
225
+ * @param {object} userOptions - User auth key and pubnub credentials
226
+ * @returns PROMISE.
227
+ */
228
+ var __setup = function (userOptions) {
229
+
230
+ var pubnubConfig = userOptions.pubnub;
231
+ pubnubConfig.uuid = userOptions.userid;
232
+ var accountId = userOptions.accountid;
233
+ var token = userOptions.token;
234
+
235
+ if (!_pubnubClient && pubnubConfig) {
236
+ _pubnubClient = new pubNub(pubnubConfig); //Connect with PubNub SDK
237
+ _pubnubClient.setToken(token);
238
+ processSetup();
239
+ } else {
240
+ return new Error('Already Initialized');
241
+ }
283
242
 
284
243
  /**
285
- * Polling function
244
+ * SYNC Function
286
245
  */
287
- var _pollForEvents = function () {
288
- // Setup request params
289
- var params = {
290
- accountid: _userOptions.accountid,
291
- channelname: _globalSubscription[0],
292
- starttime: _startTimestampForPolling,
293
- endtime: Date.now()
294
- };
295
-
296
- // Safe check to avoid poll for events if the channel name or start time is not set
297
- // This handles an edge condition where the clearTimeout doesn't work as expected
298
- if (!params.channelname || !params.starttime) {
299
- return;
246
+ function processSetup() {
247
+ _userOptions = userOptions;
248
+ _pubnubClient.addListener({ //Setup Listeners (events will shows up after subscription)
249
+ 'message': function (data) {
250
+ _translatePubnubMessage(data);
251
+ },
252
+ 'status': function (status) {
253
+ var statusOptions = { accountId: accountId };
254
+ _translatePubnubStatus(status, statusOptions);
300
255
  }
301
-
302
- var requestAPI = request.get(_userOptions.pollingEndpoint).query(params);
303
-
304
- requestAPI
305
- .end(function(error, response) {
306
-
307
- if (!error) {
308
- // Bubble the connected status
309
- if (_pollingCounter === 0) {
310
- // Set the status of the channel to subscribed
311
- if(_globalSubscriptionStatus[_globalSubscription[0]]) {
312
- _globalSubscriptionStatus[_globalSubscription[0]].status = 'subscribed';
313
- }
314
-
315
- var successObj = {
316
- category: 'PUSHX',
317
- type: 'CHANNEL_SUBSCRIPTION',
318
- status: 'SUCCESS',
319
- message: 'Success: Subscribed successfully.',
320
- httpcode: 200,
321
- data: {
322
- payload: {
323
- channels: _globalSubscription
324
- },
325
- message: 'Success: Subscribed successfully.'
326
- }
327
- };
328
- _eventEmitter.emit('pushx_status', successObj);
329
- }
330
-
331
- // Bubble the received events
332
- _bubblePolledEvents(response.body);
333
-
334
- // Increase the counter
335
- _pollingCounter++;
336
- }
337
-
338
- // Polling will be done only for specific number of times
339
- if (_pollingCounter > _userOptions.pollingIterations) {
340
- var error = {
341
- message: "Polling error: Polling limit exceeded",
342
- status: 429
343
- };
344
- error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
345
- _eventEmitter.emit('pushx_status', error);
346
- } else {
347
- var timeoutDelay;
348
-
349
- // If the polling interval is provided, use that
350
- if (_userOptions.pollingInterval) {
351
- timeoutDelay = _userOptions.pollingInterval * 60 * 1000;
352
- } else {
353
- // Else, use exponential backoff
354
- timeoutDelay = parseInt(Math.pow(1.3, _pollingCounter) * 10 * 1000, 10);
355
- }
356
-
357
- // Set timeout for next poll
358
- if (timeoutDelay) {
359
- _setTimeoutIDForPolling = setTimeout(_pollForEvents, timeoutDelay);
360
- }
361
- }
362
- });
256
+ });
257
+ }
258
+ return _constructClientAdaptor();
259
+ }; //End of _setup()
260
+
261
+ var __cleanup = function () {
262
+ if (_pubnubClient) { //Skip cleanup if setup() was not called.
263
+ _pubnubClient.unsubscribeAll();
264
+ _pubnubClient.stop();
265
+ _globalSubscription = [];
266
+ bStatusSubscribed = false;
267
+ _globalSubscriptionStatus = {};
268
+ bPollingInitiated = false;
269
+ }
270
+ _pubnubClient = undefined;
271
+
272
+ // Clear the Polling
273
+ if (_setTimeoutIDForPolling) {
274
+ clearTimeout(_setTimeoutIDForPolling);
275
+ // Setting the start time to now to clear the old events
276
+ _startTimestampForPolling = Date.now();
277
+ _checkOldBubbledEvents();
278
+ _setTimeoutIDForPolling = undefined;
279
+ _pollingCounter = undefined;
280
+ _startTimestampForPolling = undefined;
281
+ }
282
+ };
283
+
284
+ /**
285
+ * Polling function
286
+ */
287
+ var _pollForEvents = function () {
288
+ // Setup request params
289
+ var params = {
290
+ accountid: _userOptions.accountid,
291
+ channelname: _globalSubscription[0],
292
+ starttime: _startTimestampForPolling,
293
+ endtime: Date.now()
363
294
  };
364
295
 
365
- /**
366
- * Bubble the polled events to the FE APP
367
- * @param {*} events - Events recieved from the polling endpoint
368
- */
369
- var _bubblePolledEvents = function (events) {
370
- // Load the old events from the session storage
371
- var oldEventData = _checkOldBubbledEvents();
372
-
373
- var oldEvents = oldEventData.events;
374
- var sessionStorageKey = oldEventData.key;
296
+ // Safe check to avoid poll for events if the channel name or start time is not set
297
+ // This handles an edge condition where the clearTimeout doesn't work as expected
298
+ if (!params.channelname || !params.starttime) {
299
+ return;
300
+ }
301
+
302
+ var requestAPI = request.get(_userOptions.pollingEndpoint).query(params);
303
+
304
+ requestAPI
305
+ .end(function(error, response) {
306
+
307
+ if (!error) {
308
+ // Bubble the connected status
309
+ if (_pollingCounter === 0) {
310
+ // Set the status of the channel to subscribed
311
+ if(_globalSubscriptionStatus[_globalSubscription[0]]) {
312
+ _globalSubscriptionStatus[_globalSubscription[0]].status = 'subscribed';
313
+ }
314
+
315
+ var successObj = {
316
+ category: 'PUSHX',
317
+ type: 'CHANNEL_SUBSCRIPTION',
318
+ status: 'SUCCESS',
319
+ message: 'Success: Subscribed successfully.',
320
+ httpcode: 200,
321
+ data: {
322
+ payload: {
323
+ channels: _globalSubscription
324
+ },
325
+ message: 'Success: Subscribed successfully.'
326
+ }
327
+ };
328
+ _eventEmitter.emit('pushx_status', successObj);
329
+ }
375
330
 
376
- for (var i = 0; i < events.entities.length; i++) {
377
- var event = events.entities[i];
378
- var eventId = event.pk + '_' + event.sk;
331
+ // Bubble the received events
332
+ _bubblePolledEvents(response.body);
379
333
 
380
- // Check if the event is already emitted
381
- if (!oldEvents[eventId]) {
382
- oldEvents[eventId] = event.context.start_time;
334
+ // Increase the counter
335
+ _pollingCounter++;
336
+ }
383
337
 
384
- // Emit the event
385
- _eventEmitter.emit(_globalSubscription[0], event);
386
- }
338
+ // Polling will be done only for specific number of times
339
+ if (_pollingCounter > _userOptions.pollingIterations) {
340
+ var error = {
341
+ message: 'Polling error: Polling limit exceeded',
342
+ status: 429
343
+ };
344
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
345
+ _eventEmitter.emit('pushx_status', error);
346
+ } else {
347
+ var timeoutDelay;
348
+
349
+ // If the polling interval is provided, use that
350
+ if (_userOptions.pollingInterval) {
351
+ timeoutDelay = _userOptions.pollingInterval * 60 * 1000;
352
+ } else {
353
+ // Else, use exponential backoff
354
+ timeoutDelay = parseInt(Math.pow(1.3, _pollingCounter) * 10 * 1000, 10);
387
355
  }
388
356
 
389
- // Save the bubbled events to session storage
390
- sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
391
- };
392
-
393
- /**
394
- * Check the old bubbled events and remove the events that are older than the start timestamp
395
- * @returns {object} - Object containing the key and the events
396
- */
397
- var _checkOldBubbledEvents = function () {
398
- var sessionStorageKey = 'comprodls.old_pushx_events.' + _userOptions.userid + '.' + _globalSubscription[0];
399
- var oldEvents = sessionStorage.getItem(sessionStorageKey);
400
-
401
- if (oldEvents) {
402
- try {
403
- oldEvents = JSON.parse(oldEvents);
404
- } catch (e) {
405
- oldEvents = {};
406
- }
357
+ // Set timeout for next poll
358
+ if (timeoutDelay) {
359
+ _setTimeoutIDForPolling = setTimeout(_pollForEvents, timeoutDelay);
360
+ }
361
+ }
362
+ });
363
+ };
364
+
365
+ /**
366
+ * Bubble the polled events to the FE APP
367
+ * @param {*} events - Events recieved from the polling endpoint
368
+ */
369
+ var _bubblePolledEvents = function (events) {
370
+ // Load the old events from the session storage
371
+ var oldEventData = _checkOldBubbledEvents();
372
+
373
+ var oldEvents = oldEventData.events;
374
+ var sessionStorageKey = oldEventData.key;
375
+
376
+ for (var i = 0; i < events.entities.length; i++) {
377
+ var event = events.entities[i];
378
+ var eventId = event.pk + '_' + event.sk;
379
+
380
+ // Check if the event is already emitted
381
+ if (!oldEvents[eventId]) {
382
+ oldEvents[eventId] = event.context.start_time;
383
+
384
+ // Emit the event
385
+ _eventEmitter.emit(_globalSubscription[0], event);
386
+ }
387
+ }
388
+
389
+ // Save the bubbled events to session storage
390
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
391
+ };
392
+
393
+ /**
394
+ * Check the old bubbled events and remove the events that are older than the start timestamp
395
+ * @returns {object} - Object containing the key and the events
396
+ */
397
+ var _checkOldBubbledEvents = function () {
398
+ var sessionStorageKey = 'comprodls.old_pushx_events.' + _userOptions.userid + '.' + _globalSubscription[0];
399
+ var oldEvents = sessionStorage.getItem(sessionStorageKey);
400
+
401
+ if (oldEvents) {
402
+ try {
403
+ oldEvents = JSON.parse(oldEvents);
404
+ } catch (e) {
405
+ oldEvents = {};
406
+ }
407
407
 
408
- var oldEventIds = Object.keys(oldEvents);
408
+ var oldEventIds = Object.keys(oldEvents);
409
409
 
410
- // Remove the events that are older than the start timestamp
411
- for (var i = 0; i < oldEventIds.length; i++) {
412
- var oldEventId = oldEventIds[i];
410
+ // Remove the events that are older than the start timestamp
411
+ for (var i = 0; i < oldEventIds.length; i++) {
412
+ var oldEventId = oldEventIds[i];
413
413
 
414
- if (oldEvents[oldEventId] < _startTimestampForPolling) {
415
- delete oldEvents[oldEventId];
416
- }
414
+ if (oldEvents[oldEventId] < _startTimestampForPolling) {
415
+ delete oldEvents[oldEventId];
417
416
  }
417
+ }
418
418
 
419
- // If the number of events has changed, save the events
420
- if (oldEventIds.length !== Object.keys(oldEvents).length) {
421
- sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
422
- }
423
- } else {
424
- oldEvents = {};
419
+ // If the number of events has changed, save the events
420
+ if (oldEventIds.length !== Object.keys(oldEvents).length) {
421
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
425
422
  }
423
+ } else {
424
+ oldEvents = {};
425
+ }
426
426
 
427
- return {
428
- key: sessionStorageKey,
429
- events: oldEvents
430
- };
427
+ return {
428
+ key: sessionStorageKey,
429
+ events: oldEvents
431
430
  };
431
+ };
432
432
 
433
- return { // Return public methods for the wrapper
434
- "setup": __setup,
435
- "cleanup": __cleanup
436
- };
433
+ return { // Return public methods for the wrapper
434
+ 'setup': __setup,
435
+ 'cleanup': __cleanup
436
+ };
437
437
 
438
438
  }; //End of Client Wrapper module