comprodls-sdk 2.78.0 → 2.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -923,9 +923,7 @@ function validateGenericAPICaller(apiName, method, url, params) {
923
923
  var ERROR_TYPES = {
924
924
  "API_ERROR": "API_ERROR",
925
925
  "SDK_ERROR": "SDK_ERROR",
926
- "CHANNEL_SUBSCRIPTION": "CHANNEL_SUBSCRIPTION",
927
- "UNEXPECTED_ERROR": "UNEXPECTED_ERROR",
928
- "POLLING_INITIATION": "POLLING_INITIATION"
926
+ "CHANNEL_SUBSCRIPTION": "CHANNEL_SUBSCRIPTION"
929
927
  };
930
928
 
931
929
  var ERROR_CATEGORY = {
@@ -12862,8 +12860,11 @@ function _connect(pubnubCW, options) {
12862
12860
  'publishKey': options.publishKey,
12863
12861
  'subscribeKey': options.subscribeKey,
12864
12862
  'ssl': true
12865
- }
12866
- });
12863
+ },
12864
+ 'pollingEndpoint': options.pollingEndpoint,
12865
+ 'pollingIterations': options.pollingIterations || 10, // Default polling iterations is 10
12866
+ 'pollingInterval': options.pollingInterval, // Default polling interval is exponential backoff
12867
+ });
12867
12868
  }
12868
12869
 
12869
12870
  function _cleanup(pubnubCW) { pubnubCW.cleanup(); }
@@ -13034,6 +13035,7 @@ function getPushedEvents(options) {
13034
13035
 
13035
13036
  },{"../../helpers":3,"./pubnubClientWrapper":26,"agentkeepalive":36,"q":46,"superagent":49}],26:[function(require,module,exports){
13036
13037
  var pubNub = require("pubnub");
13038
+ var request = require('superagent');
13037
13039
  var EventEmitter = require("events").EventEmitter;
13038
13040
  var helpers = require('../../helpers');
13039
13041
 
@@ -13056,6 +13058,13 @@ module.exports = function () {
13056
13058
  var _globalSubscription = [];
13057
13059
  var _globalSubscriptionStatus = {};
13058
13060
  var bStatusSubscribed = false;
13061
+ /** ID of the setTimeout - used for Polling events when PubNub fails */
13062
+ var _setTimeoutIDForPolling;
13063
+ /** Timestamp from when the events need to be fetched */
13064
+ var _startTimestampForPolling;
13065
+ /** Counter for polling */
13066
+ var _pollingCounter;
13067
+ var bPollingInitiated = false;
13059
13068
 
13060
13069
  /** ###### END OF MODULE GLOBALS */
13061
13070
 
@@ -13071,6 +13080,9 @@ module.exports = function () {
13071
13080
  //Returning the adaptor (Plain Javascript object)
13072
13081
  return {
13073
13082
  "on": function (channelObj, handler) {
13083
+ // If PubNub fails, we will fetch the events from this timestamp
13084
+ _startTimestampForPolling = Date.now();
13085
+
13074
13086
  var pubNubChannel;
13075
13087
  var channelContext = [];
13076
13088
 
@@ -13099,6 +13111,9 @@ module.exports = function () {
13099
13111
  _eventEmitter.on(channelObj.channel, handler);
13100
13112
  bStatusSubscribed = true;
13101
13113
  }
13114
+
13115
+ // Clean up the old events
13116
+ _checkOldBubbledEvents();
13102
13117
  },
13103
13118
  "getMySubscriptionStatus": __getMySubscriptionStatus
13104
13119
  };
@@ -13112,6 +13127,10 @@ module.exports = function () {
13112
13127
 
13113
13128
  var _translatePubnubStatus = function(status, options) {
13114
13129
  var channels = [], error, successObj;
13130
+
13131
+ // If polling has been initiated, ignore all punnub status
13132
+ if (bPollingInitiated) return;
13133
+
13115
13134
  switch (status.category) {
13116
13135
  case "PNConnectedCategory":
13117
13136
  if(status.operation === "PNSubscribeOperation") {
@@ -13173,11 +13192,10 @@ module.exports = function () {
13173
13192
  break;
13174
13193
  case "PNNetworkIssuesCategory":
13175
13194
  if(status.operation === 'PNSubscribeOperation') {
13176
- if(!options.accountId) {
13195
+ if(!options.accountId || !_userOptions.pollingEndpoint) {
13177
13196
  error = {
13178
- message: "Missing mandatory parameters to initiate polling operation - accountId",
13179
- status: status.statusCode,
13180
- type: helpers.errors.ERROR_TYPES.POLLING_INITIATION,
13197
+ message: "Polling initiation error: Missing mandatory parameters to initiate polling operation - [accountId, pollingEndpoint]",
13198
+ status: status.statusCode
13181
13199
  };
13182
13200
  error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
13183
13201
  _eventEmitter.emit('pushx_status', error);
@@ -13191,6 +13209,9 @@ module.exports = function () {
13191
13209
  * The wrapper supports multiple channels, but the APP currently uses a single channel only.
13192
13210
  * Polling will also limited to a single channel.
13193
13211
  */
13212
+ _pollingCounter = 0;
13213
+ _pollForEvents();
13214
+ bPollingInitiated = true;
13194
13215
  }
13195
13216
  }
13196
13217
  else {
@@ -13203,9 +13224,8 @@ module.exports = function () {
13203
13224
  default:
13204
13225
  // Emit error for other status-category received from pubnub
13205
13226
  error = {
13206
- message: "PushX Error",
13227
+ message: "PushX Error: unexpected error",
13207
13228
  status: status.statusCode,
13208
- type: helpers.errors.ERROR_TYPES.UNEXPECTED_ERROR,
13209
13229
  pushXError: status
13210
13230
  };
13211
13231
  error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
@@ -13242,6 +13262,7 @@ module.exports = function () {
13242
13262
  * @returns PROMISE.
13243
13263
  */
13244
13264
  var __setup = function (userOptions) {
13265
+
13245
13266
  var pubnubConfig = userOptions.pubnub;
13246
13267
  pubnubConfig.uuid = userOptions.userid;
13247
13268
  var accountId = userOptions.accountid;
@@ -13280,8 +13301,160 @@ module.exports = function () {
13280
13301
  _globalSubscription = [];
13281
13302
  bStatusSubscribed = false;
13282
13303
  _globalSubscriptionStatus = {};
13304
+ bPollingInitiated = false;
13283
13305
  }
13284
13306
  _pubnubClient = undefined;
13307
+
13308
+ // Clear the Polling
13309
+ if (_setTimeoutIDForPolling) {
13310
+ clearTimeout(_setTimeoutIDForPolling);
13311
+ // Setting the start time to now to clear the old events
13312
+ _startTimestampForPolling = Date.now();
13313
+ _checkOldBubbledEvents();
13314
+ _setTimeoutIDForPolling = undefined;
13315
+ _pollingCounter = undefined;
13316
+ _startTimestampForPolling = undefined;
13317
+ }
13318
+ };
13319
+
13320
+ /**
13321
+ * Polling function
13322
+ */
13323
+ var _pollForEvents = function () {
13324
+ // Setup request params
13325
+ var params = {
13326
+ accountid: _userOptions.accountid,
13327
+ channelname: _globalSubscription[0],
13328
+ starttime: _startTimestampForPolling,
13329
+ endtime: Date.now()
13330
+ };
13331
+ var requestAPI = request.get(_userOptions.pollingEndpoint).query(params);
13332
+
13333
+ requestAPI
13334
+ .end(function(error, response) {
13335
+
13336
+ if (!error) {
13337
+ // Bubble the connected status
13338
+ if (_pollingCounter === 0) {
13339
+ // Set the status of the channel to subscribed
13340
+ if(_globalSubscriptionStatus[_globalSubscription[0]]) {
13341
+ _globalSubscriptionStatus[_globalSubscription[0]].status = 'subscribed';
13342
+ }
13343
+
13344
+ var successObj = {
13345
+ category: 'PUSHX',
13346
+ type: 'CHANNEL_SUBSCRIPTION',
13347
+ status: 'SUCCESS',
13348
+ message: 'Success: Subscribed successfully.',
13349
+ httpcode: 200,
13350
+ data: {
13351
+ payload: {
13352
+ channels: _globalSubscription
13353
+ },
13354
+ message: 'Success: Subscribed successfully.'
13355
+ }
13356
+ };
13357
+ _eventEmitter.emit('pushx_status', successObj);
13358
+ }
13359
+
13360
+ // Bubble the received events
13361
+ _bubblePolledEvents(response.body);
13362
+
13363
+ // Increase the counter
13364
+ _pollingCounter++;
13365
+ }
13366
+
13367
+ // Polling will be done only for specific number of times
13368
+ if (_pollingCounter > _userOptions.pollingIterations) {
13369
+ var error = {
13370
+ message: "Polling error: Polling limit exceeded",
13371
+ status: 429
13372
+ };
13373
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
13374
+ _eventEmitter.emit('pushx_status', error);
13375
+ } else {
13376
+ var timeoutDelay;
13377
+
13378
+ // If the polling interval is provided, use that
13379
+ if (_userOptions.pollingInterval) {
13380
+ timeoutDelay = _userOptions.pollingInterval * 60 * 1000;
13381
+ } else {
13382
+ // Else, use exponential backoff
13383
+ timeoutDelay = parseInt(Math.pow(1.3, _pollingCounter) * 10 * 1000, 10);
13384
+ }
13385
+
13386
+ // Set timeout for next poll
13387
+ _setTimeoutIDForPolling = setTimeout(_pollForEvents, timeoutDelay);
13388
+ }
13389
+ });
13390
+ };
13391
+
13392
+ /**
13393
+ * Bubble the polled events to the FE APP
13394
+ * @param {*} events - Events recieved from the polling endpoint
13395
+ */
13396
+ var _bubblePolledEvents = function (events) {
13397
+ // Load the old events from the session storage
13398
+ var oldEventData = _checkOldBubbledEvents();
13399
+
13400
+ var oldEvents = oldEventData.events;
13401
+ var sessionStorageKey = oldEventData.key;
13402
+
13403
+ for (var i = 0; i < events.entities.length; i++) {
13404
+ var event = events.entities[i];
13405
+ var eventId = event.pk + '_' + event.sk;
13406
+
13407
+ // Check if the event is already emitted
13408
+ if (!oldEvents[eventId]) {
13409
+ oldEvents[eventId] = event.context.start_time;
13410
+
13411
+ // Emit the event
13412
+ _eventEmitter.emit(_globalSubscription[0], event);
13413
+ }
13414
+ }
13415
+
13416
+ // Save the bubbled events to session storage
13417
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
13418
+ };
13419
+
13420
+ /**
13421
+ * Check the old bubbled events and remove the events that are older than the start timestamp
13422
+ * @returns {object} - Object containing the key and the events
13423
+ */
13424
+ var _checkOldBubbledEvents = function () {
13425
+ var sessionStorageKey = 'comprodls.old_pushx_events.' + _userOptions.userid + '.' + _globalSubscription[0];
13426
+ var oldEvents = sessionStorage.getItem(sessionStorageKey);
13427
+
13428
+ if (oldEvents) {
13429
+ try {
13430
+ oldEvents = JSON.parse(oldEvents);
13431
+ } catch (e) {
13432
+ oldEvents = {};
13433
+ }
13434
+
13435
+ var oldEventIds = Object.keys(oldEvents);
13436
+
13437
+ // Remove the events that are older than the start timestamp
13438
+ for (var i = 0; i < oldEventIds.length; i++) {
13439
+ var oldEventId = oldEventIds[i];
13440
+
13441
+ if (oldEvents[oldEventId] < _startTimestampForPolling) {
13442
+ delete oldEvents[oldEventId];
13443
+ }
13444
+ }
13445
+
13446
+ // If the number of events has changed, save the events
13447
+ if (oldEventIds.length !== Object.keys(oldEvents).length) {
13448
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
13449
+ }
13450
+ } else {
13451
+ oldEvents = {};
13452
+ }
13453
+
13454
+ return {
13455
+ key: sessionStorageKey,
13456
+ events: oldEvents
13457
+ };
13285
13458
  };
13286
13459
 
13287
13460
  return { // Return public methods for the wrapper
@@ -13291,7 +13464,7 @@ module.exports = function () {
13291
13464
 
13292
13465
  }; //End of Client Wrapper module
13293
13466
 
13294
- },{"../../helpers":3,"events":41,"pubnub":45}],27:[function(require,module,exports){
13467
+ },{"../../helpers":3,"events":41,"pubnub":45,"superagent":49}],27:[function(require,module,exports){
13295
13468
  /*************************************************************************
13296
13469
  *
13297
13470
  * COMPRO CONFIDENTIAL