comprodls-sdk 2.77.1 → 2.79.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.
@@ -80,7 +80,10 @@ function _connect(pubnubCW, options) {
80
80
  'publishKey': options.publishKey,
81
81
  'subscribeKey': options.subscribeKey,
82
82
  'ssl': true
83
- }
83
+ },
84
+ 'pollingEndpoint': options.pollingEndpoint,
85
+ 'pollingIterations': options.pollingIterations || 10, // Default polling iterations is 10
86
+ 'pollingInterval': options.pollingInterval || 1, // Default polling interval is 1 minute
84
87
  });
85
88
  }
86
89
 
@@ -1,4 +1,5 @@
1
1
  var pubNub = require("pubnub");
2
+ var request = require('superagent');
2
3
  var EventEmitter = require("events").EventEmitter;
3
4
  var helpers = require('../../helpers');
4
5
 
@@ -21,6 +22,12 @@ module.exports = function () {
21
22
  var _globalSubscription = [];
22
23
  var _globalSubscriptionStatus = {};
23
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;
24
31
  var bPollingInitiated = false;
25
32
 
26
33
  /** ###### END OF MODULE GLOBALS */
@@ -37,6 +44,9 @@ module.exports = function () {
37
44
  //Returning the adaptor (Plain Javascript object)
38
45
  return {
39
46
  "on": function (channelObj, handler) {
47
+ // If PubNub fails, we will fetch the events from this timestamp
48
+ _startTimestampForPolling = Date.now();
49
+
40
50
  var pubNubChannel;
41
51
  var channelContext = [];
42
52
 
@@ -65,6 +75,9 @@ module.exports = function () {
65
75
  _eventEmitter.on(channelObj.channel, handler);
66
76
  bStatusSubscribed = true;
67
77
  }
78
+
79
+ // Clean up the old events
80
+ _checkOldBubbledEvents();
68
81
  },
69
82
  "getMySubscriptionStatus": __getMySubscriptionStatus
70
83
  };
@@ -143,9 +156,9 @@ module.exports = function () {
143
156
  break;
144
157
  case "PNNetworkIssuesCategory":
145
158
  if(status.operation === 'PNSubscribeOperation') {
146
- if(!options.accountId) {
159
+ if(!options.accountId || !_userOptions.pollingEndpoint) {
147
160
  error = {
148
- message: "Polling initiation error: Missing mandatory parameters to initiate polling operation - accountId",
161
+ message: "Polling initiation error: Missing mandatory parameters to initiate polling operation - [accountId, pollingEndpoint]",
149
162
  status: status.statusCode
150
163
  };
151
164
  error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
@@ -160,6 +173,8 @@ module.exports = function () {
160
173
  * The wrapper supports multiple channels, but the APP currently uses a single channel only.
161
174
  * Polling will also limited to a single channel.
162
175
  */
176
+ _pollingCounter = 0;
177
+ _pollForEvents();
163
178
  bPollingInitiated = true;
164
179
  }
165
180
  }
@@ -211,6 +226,7 @@ module.exports = function () {
211
226
  * @returns PROMISE.
212
227
  */
213
228
  var __setup = function (userOptions) {
229
+
214
230
  var pubnubConfig = userOptions.pubnub;
215
231
  pubnubConfig.uuid = userOptions.userid;
216
232
  var accountId = userOptions.accountid;
@@ -252,6 +268,147 @@ module.exports = function () {
252
268
  bPollingInitiated = false;
253
269
  }
254
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()
294
+ };
295
+ var requestAPI = request.get(_userOptions.pollingEndpoint).query(params);
296
+
297
+ requestAPI
298
+ .end(function(error, response) {
299
+
300
+ if (!error) {
301
+ // Bubble the connected status
302
+ if (_pollingCounter === 0) {
303
+ // Set the status of the channel to subscribed
304
+ if(_globalSubscriptionStatus[_globalSubscription[0]]) {
305
+ _globalSubscriptionStatus[_globalSubscription[0]].status = 'subscribed';
306
+ }
307
+
308
+ var successObj = {
309
+ category: 'PUSHX',
310
+ type: 'CHANNEL_SUBSCRIPTION',
311
+ status: 'SUCCESS',
312
+ message: 'Success: Subscribed successfully.',
313
+ httpcode: 200,
314
+ data: {
315
+ payload: {
316
+ channels: _globalSubscription
317
+ },
318
+ message: 'Success: Subscribed successfully.'
319
+ }
320
+ };
321
+ _eventEmitter.emit('pushx_status', successObj);
322
+ }
323
+
324
+ // Bubble the received events
325
+ _bubblePolledEvents(response.body);
326
+
327
+ // Increase the counter
328
+ _pollingCounter++;
329
+ }
330
+
331
+ // Polling will be done only for specific number of times
332
+ if (_pollingCounter > _userOptions.pollingIterations) {
333
+ var error = {
334
+ message: "Polling error: Polling limit exceeded",
335
+ status: 429
336
+ };
337
+ error = new PUSHXError(helpers.errors.ERROR_CATEGORY.PUSHX, error);
338
+ _eventEmitter.emit('pushx_status', error);
339
+ } else {
340
+ // Set timeout for next poll
341
+ _setTimeoutIDForPolling = setTimeout(_pollForEvents, _userOptions.pollingInterval * 60 * 1000);
342
+ }
343
+ });
344
+ };
345
+
346
+ /**
347
+ * Bubble the polled events to the FE APP
348
+ * @param {*} events - Events recieved from the polling endpoint
349
+ */
350
+ var _bubblePolledEvents = function (events) {
351
+ // Load the old events from the session storage
352
+ var oldEventData = _checkOldBubbledEvents();
353
+
354
+ var oldEvents = oldEventData.events;
355
+ var sessionStorageKey = oldEventData.key;
356
+
357
+ for (var i = 0; i < events.entities.length; i++) {
358
+ var event = events.entities[i];
359
+ var eventId = event.pk + '_' + event.sk;
360
+
361
+ // Check if the event is already emitted
362
+ if (!oldEvents[eventId]) {
363
+ oldEvents[eventId] = event.context.start_time;
364
+
365
+ // Emit the event
366
+ _eventEmitter.emit(_globalSubscription[0], event);
367
+ }
368
+ }
369
+
370
+ // Save the bubbled events to session storage
371
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
372
+ };
373
+
374
+ /**
375
+ * Check the old bubbled events and remove the events that are older than the start timestamp
376
+ * @returns {object} - Object containing the key and the events
377
+ */
378
+ var _checkOldBubbledEvents = function () {
379
+ var sessionStorageKey = 'comprodls.old_pushx_events.' + _userOptions.userid + '.' + _globalSubscription[0];
380
+ var oldEvents = sessionStorage.getItem(sessionStorageKey);
381
+
382
+ if (oldEvents) {
383
+ try {
384
+ oldEvents = JSON.parse(oldEvents);
385
+ } catch (e) {
386
+ oldEvents = {};
387
+ }
388
+
389
+ var oldEventIds = Object.keys(oldEvents);
390
+
391
+ // Remove the events that are older than the start timestamp
392
+ for (var i = 0; i < oldEventIds.length; i++) {
393
+ var oldEventId = oldEventIds[i];
394
+
395
+ if (oldEvents[oldEventId] < _startTimestampForPolling) {
396
+ delete oldEvents[oldEventId];
397
+ }
398
+ }
399
+
400
+ // If the number of events has changed, save the events
401
+ if (oldEventIds.length !== Object.keys(oldEvents).length) {
402
+ sessionStorage.setItem(sessionStorageKey, JSON.stringify(oldEvents));
403
+ }
404
+ } else {
405
+ oldEvents = {};
406
+ }
407
+
408
+ return {
409
+ key: sessionStorageKey,
410
+ events: oldEvents
411
+ };
255
412
  };
256
413
 
257
414
  return { // Return public methods for the wrapper
@@ -524,6 +524,7 @@ function provisionBulkSpaces(options) {
524
524
  * *startdate: <epoch>,
525
525
  * *enddate: <epoch>,
526
526
  * description: 'string',
527
+ * ext_class_title : 'string',
527
528
  * ext_data: {},
528
529
  * limits: {
529
530
  * *los: 0,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "comprodls-sdk",
3
3
  "description": "comproDLS SDK for JavaScript",
4
- "version": "2.77.1",
4
+ "version": "2.79.0",
5
5
  "author": {
6
6
  "name": "Compro Technologies Private Limited",
7
7
  "url": "http://www.comprotechnologies.com/"