quickblox 2.20.0 → 2.21.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/quickblox.d.ts +12 -0
- package/quickblox.js +263 -16
- package/src/qbConfig.js +5 -2
- package/src/qbMain.js +146 -11
- package/src/qbProxy.js +46 -1
- package/src/qbUtils.js +66 -2
package/package.json
CHANGED
package/quickblox.d.ts
CHANGED
|
@@ -141,8 +141,13 @@ export declare interface QBConfig {
|
|
|
141
141
|
) => void
|
|
142
142
|
}
|
|
143
143
|
pingTimeout?: number
|
|
144
|
+
pingDebug?: boolean
|
|
144
145
|
pingLocalhostTimeInterval?: number
|
|
145
146
|
chatReconnectionTimeInterval?: number
|
|
147
|
+
/** If true, QB.init will do a short synchronous block after starting account_settings. Default: true. */
|
|
148
|
+
initBlockOnSettings?: boolean
|
|
149
|
+
/** Busy-wait duration in ms used when initBlockOnSettings=true. Default: 3000. */
|
|
150
|
+
initBlockDurationMs?: number
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
export declare interface QBError {
|
|
@@ -1636,6 +1641,13 @@ export class QuickBlox {
|
|
|
1636
1641
|
config?: QBConfig,
|
|
1637
1642
|
): void
|
|
1638
1643
|
|
|
1644
|
+
/**
|
|
1645
|
+
* Resolves when internal async initialization (e.g., fetching `account_settings`
|
|
1646
|
+
* and rebinding endpoints) is finished. If no async work was scheduled during
|
|
1647
|
+
* `init`, it resolves immediately.
|
|
1648
|
+
*/
|
|
1649
|
+
ready(): Promise<void>
|
|
1650
|
+
|
|
1639
1651
|
/**
|
|
1640
1652
|
* Init QuickBlox SDK with User Account data to start session with token
|
|
1641
1653
|
* ([read more](https://docs.quickblox.com/docs/js-setup#initialize-quickblox-sdk-without-authorization-key-and-secret)).
|
package/quickblox.js
CHANGED
|
@@ -55078,8 +55078,8 @@ module.exports = StreamManagement;
|
|
|
55078
55078
|
*/
|
|
55079
55079
|
|
|
55080
55080
|
var config = {
|
|
55081
|
-
version: '2.
|
|
55082
|
-
buildNumber: '
|
|
55081
|
+
version: '2.21.0',
|
|
55082
|
+
buildNumber: '1167',
|
|
55083
55083
|
creds: {
|
|
55084
55084
|
'appId': 0,
|
|
55085
55085
|
'authKey': '',
|
|
@@ -55101,6 +55101,9 @@ var config = {
|
|
|
55101
55101
|
active: 2
|
|
55102
55102
|
},
|
|
55103
55103
|
pingTimeout: 1,
|
|
55104
|
+
pingDebug: false,
|
|
55105
|
+
initBlockOnSettings: false,
|
|
55106
|
+
initBlockDurationMs: 3000,
|
|
55104
55107
|
pingLocalhostTimeInterval: 5,
|
|
55105
55108
|
chatReconnectionTimeInterval: 3,
|
|
55106
55109
|
webrtc: {
|
|
@@ -55206,6 +55209,10 @@ module.exports = config;
|
|
|
55206
55209
|
var config = require('./qbConfig');
|
|
55207
55210
|
var Utils = require('./qbUtils');
|
|
55208
55211
|
const MessageProxy = require("./modules/chat/qbMessage");
|
|
55212
|
+
const Chat = require("./modules/chat/qbChat");
|
|
55213
|
+
const DialogProxy = require("./modules/chat/qbDialog");
|
|
55214
|
+
const WebRTCClient = require("./modules/webrtc/qbWebRTCClient");
|
|
55215
|
+
const PushNotifications = require("./modules/qbPushNotifications");
|
|
55209
55216
|
|
|
55210
55217
|
// Actual QuickBlox API starts here
|
|
55211
55218
|
function QuickBlox() {}
|
|
@@ -55290,6 +55297,10 @@ QuickBlox.prototype = {
|
|
|
55290
55297
|
} else {
|
|
55291
55298
|
this.webrtc = false;
|
|
55292
55299
|
}
|
|
55300
|
+
this._initReady = Promise.resolve();
|
|
55301
|
+
var initBlockOnSettings = (typeof config.initBlockOnSettings === 'boolean') ? config.initBlockOnSettings : true;
|
|
55302
|
+
var initBlockDurationMs = (typeof config.initBlockDurationMs === 'number') ? config.initBlockDurationMs : 3000;
|
|
55303
|
+
|
|
55293
55304
|
|
|
55294
55305
|
// Initialization by outside token
|
|
55295
55306
|
if (typeof appIdOrToken === 'string' && (!authKeyOrAppId || typeof authKeyOrAppId === 'number') && !authSecret) {
|
|
@@ -55317,21 +55328,148 @@ QuickBlox.prototype = {
|
|
|
55317
55328
|
config.urls.account,
|
|
55318
55329
|
config.urls.type
|
|
55319
55330
|
].join('');
|
|
55331
|
+
|
|
55332
|
+
// generic function to capture (extract) listeners
|
|
55333
|
+
var preserveListeners = function (obj) {
|
|
55334
|
+
var map = {};
|
|
55335
|
+
if (!obj) return map;
|
|
55336
|
+
Object.keys(obj).forEach(function (k) {
|
|
55337
|
+
if (/^on[A-Z]/.test(k) && typeof obj[k] === 'function') {
|
|
55338
|
+
map[k] = obj[k];
|
|
55339
|
+
}
|
|
55340
|
+
});
|
|
55341
|
+
return map;
|
|
55342
|
+
};
|
|
55343
|
+
|
|
55344
|
+
// restore
|
|
55345
|
+
var reassignListeners = function (target, map) {
|
|
55346
|
+
if (!target || !map) return;
|
|
55347
|
+
Object.keys(map).forEach(function (k) {
|
|
55348
|
+
target[k] = map[k];
|
|
55349
|
+
});
|
|
55350
|
+
};
|
|
55351
|
+
|
|
55320
55352
|
// account settings
|
|
55321
|
-
this
|
|
55322
|
-
|
|
55323
|
-
|
|
55324
|
-
|
|
55325
|
-
|
|
55326
|
-
|
|
55327
|
-
|
|
55328
|
-
|
|
55353
|
+
var self = this;
|
|
55354
|
+
//
|
|
55355
|
+
this._initReady = new Promise(function(resolve) {
|
|
55356
|
+
self.service.ajax({ url: accountSettingsUrl }, function (err, response) {
|
|
55357
|
+
// resolve in any case (so legacy clients won’t hang)
|
|
55358
|
+
if (!err && typeof response === 'object') {
|
|
55359
|
+
// 1) apply endpoints
|
|
55360
|
+
var update = {
|
|
55361
|
+
endpoints: {
|
|
55362
|
+
api: response.api_endpoint.replace(/^https?:\/\//, ''),
|
|
55363
|
+
chat: response.chat_endpoint
|
|
55364
|
+
}
|
|
55365
|
+
};
|
|
55366
|
+
config.set(update);
|
|
55367
|
+
|
|
55368
|
+
// 2) preserve ALL previously assigned listeners (dynamically)
|
|
55369
|
+
var savedChatListeners = preserveListeners(self.chat);
|
|
55370
|
+
var savedWebRTCListeners = preserveListeners(self.webrtc);
|
|
55371
|
+
|
|
55372
|
+
// 3) re-create dependent components for the new endpoints
|
|
55373
|
+
self.pushnotifications = new PushNotifications(self.service);
|
|
55374
|
+
self.chat = new Chat(self.service);
|
|
55375
|
+
self.chat.dialog = new DialogProxy(self.service);
|
|
55376
|
+
self.chat.message = new MessageProxy(self.service);
|
|
55377
|
+
|
|
55378
|
+
if (Utils.getEnv().browser) {
|
|
55379
|
+
require('webrtc-adapter');
|
|
55380
|
+
if (Utils.isWebRTCAvailble()) {
|
|
55381
|
+
var WebRTCClient = require('./modules/webrtc/qbWebRTCClient');
|
|
55382
|
+
self.webrtc = new WebRTCClient(self.service, self.chat);
|
|
55383
|
+
} else {
|
|
55384
|
+
self.webrtc = false;
|
|
55385
|
+
}
|
|
55386
|
+
} else {
|
|
55387
|
+
self.webrtc = false;
|
|
55329
55388
|
}
|
|
55330
|
-
|
|
55331
|
-
|
|
55332
|
-
|
|
55389
|
+
|
|
55390
|
+
// 4) reattach listeners to the new instances
|
|
55391
|
+
reassignListeners(self.chat, savedChatListeners);
|
|
55392
|
+
reassignListeners(self.webrtc, savedWebRTCListeners);
|
|
55393
|
+
}
|
|
55394
|
+
|
|
55395
|
+
resolve(); // init completed (with or without migration)
|
|
55396
|
+
});
|
|
55333
55397
|
});
|
|
55398
|
+
//
|
|
55399
|
+
// previous version with callback
|
|
55400
|
+
// this.service.ajax({
|
|
55401
|
+
// url: accountSettingsUrl
|
|
55402
|
+
// }, function (err, response) {
|
|
55403
|
+
// if (!err && typeof response === 'object') {
|
|
55404
|
+
// var update = {
|
|
55405
|
+
// endpoints: {
|
|
55406
|
+
// api: response.api_endpoint.replace(/^https?:\/\//, ''),
|
|
55407
|
+
// chat: response.chat_endpoint
|
|
55408
|
+
// }
|
|
55409
|
+
// };
|
|
55410
|
+
// config.set(update);
|
|
55411
|
+
// //
|
|
55412
|
+
// self.pushnotifications = new PushNotifications(self.service);
|
|
55413
|
+
// self.chat = new Chat(self.service);
|
|
55414
|
+
// self.chat.dialog = new DialogProxy(self.service);
|
|
55415
|
+
// self.chat.message = new MessageProxy(self.service);
|
|
55416
|
+
// //
|
|
55417
|
+
// if (Utils.getEnv().browser) {
|
|
55418
|
+
// /** add adapter.js*/
|
|
55419
|
+
// require('webrtc-adapter');
|
|
55420
|
+
//
|
|
55421
|
+
// /** add WebRTC API if API is avaible */
|
|
55422
|
+
// if( Utils.isWebRTCAvailble() ) {
|
|
55423
|
+
// var WebRTCClient = require('./modules/webrtc/qbWebRTCClient');
|
|
55424
|
+
// self.webrtc = new WebRTCClient(self.service, self.chat);
|
|
55425
|
+
// } else {
|
|
55426
|
+
// self.webrtc = false;
|
|
55427
|
+
// }
|
|
55428
|
+
// } else {
|
|
55429
|
+
// self.webrtc = false;
|
|
55430
|
+
// }
|
|
55431
|
+
// //
|
|
55432
|
+
// }
|
|
55433
|
+
// });
|
|
55434
|
+
//
|
|
55435
|
+
}
|
|
55436
|
+
//
|
|
55437
|
+
// --- artificial sync delay to increase the chance account_settings completes before legacy code continues
|
|
55438
|
+
// enabled only when shouldGetSettings && config.initBlockOnSettings !== false
|
|
55439
|
+
if (shouldGetSettings && initBlockOnSettings) {
|
|
55440
|
+
try {
|
|
55441
|
+
var __qb_init_block_until__ = Date.now() + initBlockDurationMs;
|
|
55442
|
+
while (Date.now() < __qb_init_block_until__) {
|
|
55443
|
+
// intentional busy-wait (do not remove)
|
|
55444
|
+
}
|
|
55445
|
+
} catch (_) { /* never throw from here */ }
|
|
55334
55446
|
}
|
|
55447
|
+
//
|
|
55448
|
+
|
|
55449
|
+
},
|
|
55450
|
+
|
|
55451
|
+
/**
|
|
55452
|
+
* Wait until SDK async initialization finishes (if any).
|
|
55453
|
+
* It resolves after internal tasks like fetching `account_settings`,
|
|
55454
|
+
* rebinding endpoints, and re-instantiating dependent modules are completed.
|
|
55455
|
+
* If no async work was scheduled during `QB.init(...)`, it resolves immediately.
|
|
55456
|
+
*
|
|
55457
|
+
* @memberof QB
|
|
55458
|
+
* @returns {Promise<void>} A promise that resolves when initialization is complete.
|
|
55459
|
+
*
|
|
55460
|
+
* @example
|
|
55461
|
+
* QB.init(appId, authKey, authSecret, accountKey, config);
|
|
55462
|
+
* QB.ready().then(function () {
|
|
55463
|
+
* // Safe point: endpoints are updated, chat/webrtc are re-created, listeners preserved.
|
|
55464
|
+
* QB.startSession({ login: 'john', password: 'secret' }, function (err, res) {
|
|
55465
|
+
* if (!err) {
|
|
55466
|
+
* QB.chat.connect({ userId: res.user.id, password: res.session.token }, function(){});
|
|
55467
|
+
* }
|
|
55468
|
+
* });
|
|
55469
|
+
* });
|
|
55470
|
+
*/
|
|
55471
|
+
ready: function() {
|
|
55472
|
+
return this._initReady || Promise.resolve();
|
|
55335
55473
|
},
|
|
55336
55474
|
|
|
55337
55475
|
/**
|
|
@@ -55755,13 +55893,58 @@ ServiceProxy.prototype = {
|
|
|
55755
55893
|
|
|
55756
55894
|
self.handleResponse(null, body, callback, retry);
|
|
55757
55895
|
}
|
|
55896
|
+
// if (self._fetchingSettings) {
|
|
55897
|
+
// self._fetchingSettings = false;
|
|
55898
|
+
// while (self._queue.length) {
|
|
55899
|
+
// var args = self._queue.shift();
|
|
55900
|
+
// self.ajax.apply(self, args);
|
|
55901
|
+
// }
|
|
55902
|
+
// }
|
|
55903
|
+
//
|
|
55758
55904
|
if (self._fetchingSettings) {
|
|
55759
55905
|
self._fetchingSettings = false;
|
|
55906
|
+
|
|
55907
|
+
var sharedApiHost = 'api.quickblox.com';
|
|
55908
|
+
var sharedChatHost = 'chat.quickblox.com';
|
|
55909
|
+
|
|
55910
|
+
sharedApiHost = sharedApiHost.replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
55911
|
+
sharedChatHost = sharedChatHost.replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
55912
|
+
|
|
55913
|
+
var RE_SHARED_API = new RegExp('^https?://' + sharedApiHost.replace(/\./g, '\\.') + '(?=[:/]|$)', 'i');
|
|
55914
|
+
var RE_SHARED_CHAT = new RegExp('^https?://' + sharedChatHost.replace(/\./g, '\\.') + '(?=[:/]|$)', 'i');
|
|
55915
|
+
|
|
55916
|
+
var newApiHost = (self.qbInst.config.endpoints.api || '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
55917
|
+
var newChatHost = (self.qbInst.config.endpoints.chat || '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
55918
|
+
var NEW_API_URL = 'https://' + newApiHost;
|
|
55919
|
+
var NEW_CHAT_URL = 'https://' + newChatHost;
|
|
55920
|
+
|
|
55760
55921
|
while (self._queue.length) {
|
|
55761
|
-
var args = self._queue.shift();
|
|
55922
|
+
var args = self._queue.shift(); // [params, callback]
|
|
55923
|
+
var p = args && args[0];
|
|
55924
|
+
|
|
55925
|
+
if (p && typeof p.url === 'string') {
|
|
55926
|
+
var url = p.url;
|
|
55927
|
+
var changed = false;
|
|
55928
|
+
|
|
55929
|
+
if (RE_SHARED_API.test(url)) {
|
|
55930
|
+
url = url.replace(RE_SHARED_API, NEW_API_URL);
|
|
55931
|
+
changed = true;
|
|
55932
|
+
}
|
|
55933
|
+
if (RE_SHARED_CHAT.test(url)) {
|
|
55934
|
+
url = url.replace(RE_SHARED_CHAT, NEW_CHAT_URL);
|
|
55935
|
+
changed = true;
|
|
55936
|
+
}
|
|
55937
|
+
|
|
55938
|
+
if (changed) {
|
|
55939
|
+
p.url = url;
|
|
55940
|
+
}
|
|
55941
|
+
}
|
|
55942
|
+
|
|
55762
55943
|
self.ajax.apply(self, args);
|
|
55763
55944
|
}
|
|
55764
55945
|
}
|
|
55946
|
+
|
|
55947
|
+
//
|
|
55765
55948
|
}
|
|
55766
55949
|
|
|
55767
55950
|
function retry(session) {
|
|
@@ -56029,9 +56212,68 @@ var Utils = {
|
|
|
56029
56212
|
},
|
|
56030
56213
|
|
|
56031
56214
|
QBLog: function(){
|
|
56215
|
+
var argsArr = Array.prototype.slice.call(arguments);
|
|
56216
|
+
|
|
56217
|
+
function containsPing(x) {
|
|
56218
|
+
var needle = 'ping';
|
|
56219
|
+
|
|
56220
|
+
try {
|
|
56221
|
+
if (x == null) return false;
|
|
56222
|
+
|
|
56223
|
+
if (typeof x === 'string') {
|
|
56224
|
+
return x.toLowerCase().indexOf(needle) !== -1;
|
|
56225
|
+
}
|
|
56226
|
+
|
|
56227
|
+
if (typeof x === 'number' || typeof x === 'boolean') {
|
|
56228
|
+
return false;
|
|
56229
|
+
}
|
|
56230
|
+
|
|
56231
|
+
if (typeof x === 'object') {
|
|
56232
|
+
//DELETE XEP-0198 SM packages from log:
|
|
56233
|
+
// <r xmlns="urn:xmpp:sm:3"/> and <a xmlns="urn:xmpp:sm:3" h="..."/>
|
|
56234
|
+
if (typeof x.outerHTML === 'string') {
|
|
56235
|
+
var oh = x.outerHTML.replace(/\s+/g, ' ').toLowerCase();
|
|
56236
|
+
if (
|
|
56237
|
+
oh.indexOf('urn:xmpp:sm:3') !== -1 &&
|
|
56238
|
+
(/^<\s*r\b/.test(oh) || /^<\s*a\b/.test(oh))
|
|
56239
|
+
) {
|
|
56240
|
+
return true;
|
|
56241
|
+
}
|
|
56242
|
+
}
|
|
56243
|
+
|
|
56244
|
+
var candidates = [
|
|
56245
|
+
x.textContent,
|
|
56246
|
+
x.innerHTML,
|
|
56247
|
+
x.outerHTML,
|
|
56248
|
+
x.nodeName,
|
|
56249
|
+
x.tagName,
|
|
56250
|
+
x.id
|
|
56251
|
+
];
|
|
56252
|
+
|
|
56253
|
+
for (var j = 0; j < candidates.length; j++) {
|
|
56254
|
+
var s = candidates[j];
|
|
56255
|
+
if (typeof s === 'string' && s.toLowerCase().indexOf(needle) !== -1) {
|
|
56256
|
+
return true;
|
|
56257
|
+
}
|
|
56258
|
+
}
|
|
56259
|
+
}
|
|
56260
|
+
} catch (_) {}
|
|
56261
|
+
|
|
56262
|
+
return false;
|
|
56263
|
+
}
|
|
56264
|
+
|
|
56265
|
+
|
|
56266
|
+
let shouldSuppressPing1 =
|
|
56267
|
+
config && config.pingDebug === false;
|
|
56268
|
+
let shouldSuppressPing2 =argsArr.some(containsPing);
|
|
56269
|
+
|
|
56270
|
+
let shouldSuppressPing = shouldSuppressPing1 && shouldSuppressPing2;
|
|
56271
|
+
|
|
56032
56272
|
if (this.loggers) {
|
|
56033
56273
|
for (var i=0; i<this.loggers.length; ++i) {
|
|
56034
|
-
|
|
56274
|
+
if (!shouldSuppressPing) {
|
|
56275
|
+
this.loggers[i](arguments);
|
|
56276
|
+
}
|
|
56035
56277
|
}
|
|
56036
56278
|
|
|
56037
56279
|
return;
|
|
@@ -56112,7 +56354,12 @@ var Utils = {
|
|
|
56112
56354
|
|
|
56113
56355
|
if(this.loggers){
|
|
56114
56356
|
for(var j=0;j<this.loggers.length;++j){
|
|
56115
|
-
this.loggers[j](arguments);
|
|
56357
|
+
// this.loggers[j](arguments);
|
|
56358
|
+
//
|
|
56359
|
+
if (!shouldSuppressPing) {
|
|
56360
|
+
this.loggers[j](arguments);
|
|
56361
|
+
}
|
|
56362
|
+
//
|
|
56116
56363
|
}
|
|
56117
56364
|
}
|
|
56118
56365
|
},
|
package/src/qbConfig.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
var config = {
|
|
15
|
-
version: '2.
|
|
16
|
-
buildNumber: '
|
|
15
|
+
version: '2.21.0',
|
|
16
|
+
buildNumber: '1167',
|
|
17
17
|
creds: {
|
|
18
18
|
'appId': 0,
|
|
19
19
|
'authKey': '',
|
|
@@ -35,6 +35,9 @@ var config = {
|
|
|
35
35
|
active: 2
|
|
36
36
|
},
|
|
37
37
|
pingTimeout: 1,
|
|
38
|
+
pingDebug: false,
|
|
39
|
+
initBlockOnSettings: false,
|
|
40
|
+
initBlockDurationMs: 3000,
|
|
38
41
|
pingLocalhostTimeInterval: 5,
|
|
39
42
|
chatReconnectionTimeInterval: 3,
|
|
40
43
|
webrtc: {
|
package/src/qbMain.js
CHANGED
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
var config = require('./qbConfig');
|
|
10
10
|
var Utils = require('./qbUtils');
|
|
11
11
|
const MessageProxy = require("./modules/chat/qbMessage");
|
|
12
|
+
const Chat = require("./modules/chat/qbChat");
|
|
13
|
+
const DialogProxy = require("./modules/chat/qbDialog");
|
|
14
|
+
const WebRTCClient = require("./modules/webrtc/qbWebRTCClient");
|
|
15
|
+
const PushNotifications = require("./modules/qbPushNotifications");
|
|
12
16
|
|
|
13
17
|
// Actual QuickBlox API starts here
|
|
14
18
|
function QuickBlox() {}
|
|
@@ -93,6 +97,10 @@ QuickBlox.prototype = {
|
|
|
93
97
|
} else {
|
|
94
98
|
this.webrtc = false;
|
|
95
99
|
}
|
|
100
|
+
this._initReady = Promise.resolve();
|
|
101
|
+
var initBlockOnSettings = (typeof config.initBlockOnSettings === 'boolean') ? config.initBlockOnSettings : true;
|
|
102
|
+
var initBlockDurationMs = (typeof config.initBlockDurationMs === 'number') ? config.initBlockDurationMs : 3000;
|
|
103
|
+
|
|
96
104
|
|
|
97
105
|
// Initialization by outside token
|
|
98
106
|
if (typeof appIdOrToken === 'string' && (!authKeyOrAppId || typeof authKeyOrAppId === 'number') && !authSecret) {
|
|
@@ -120,21 +128,148 @@ QuickBlox.prototype = {
|
|
|
120
128
|
config.urls.account,
|
|
121
129
|
config.urls.type
|
|
122
130
|
].join('');
|
|
131
|
+
|
|
132
|
+
// generic function to capture (extract) listeners
|
|
133
|
+
var preserveListeners = function (obj) {
|
|
134
|
+
var map = {};
|
|
135
|
+
if (!obj) return map;
|
|
136
|
+
Object.keys(obj).forEach(function (k) {
|
|
137
|
+
if (/^on[A-Z]/.test(k) && typeof obj[k] === 'function') {
|
|
138
|
+
map[k] = obj[k];
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return map;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// restore
|
|
145
|
+
var reassignListeners = function (target, map) {
|
|
146
|
+
if (!target || !map) return;
|
|
147
|
+
Object.keys(map).forEach(function (k) {
|
|
148
|
+
target[k] = map[k];
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
|
|
123
152
|
// account settings
|
|
124
|
-
this
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
153
|
+
var self = this;
|
|
154
|
+
//
|
|
155
|
+
this._initReady = new Promise(function(resolve) {
|
|
156
|
+
self.service.ajax({ url: accountSettingsUrl }, function (err, response) {
|
|
157
|
+
// resolve in any case (so legacy clients won’t hang)
|
|
158
|
+
if (!err && typeof response === 'object') {
|
|
159
|
+
// 1) apply endpoints
|
|
160
|
+
var update = {
|
|
161
|
+
endpoints: {
|
|
162
|
+
api: response.api_endpoint.replace(/^https?:\/\//, ''),
|
|
163
|
+
chat: response.chat_endpoint
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
config.set(update);
|
|
167
|
+
|
|
168
|
+
// 2) preserve ALL previously assigned listeners (dynamically)
|
|
169
|
+
var savedChatListeners = preserveListeners(self.chat);
|
|
170
|
+
var savedWebRTCListeners = preserveListeners(self.webrtc);
|
|
171
|
+
|
|
172
|
+
// 3) re-create dependent components for the new endpoints
|
|
173
|
+
self.pushnotifications = new PushNotifications(self.service);
|
|
174
|
+
self.chat = new Chat(self.service);
|
|
175
|
+
self.chat.dialog = new DialogProxy(self.service);
|
|
176
|
+
self.chat.message = new MessageProxy(self.service);
|
|
177
|
+
|
|
178
|
+
if (Utils.getEnv().browser) {
|
|
179
|
+
require('webrtc-adapter');
|
|
180
|
+
if (Utils.isWebRTCAvailble()) {
|
|
181
|
+
var WebRTCClient = require('./modules/webrtc/qbWebRTCClient');
|
|
182
|
+
self.webrtc = new WebRTCClient(self.service, self.chat);
|
|
183
|
+
} else {
|
|
184
|
+
self.webrtc = false;
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
self.webrtc = false;
|
|
132
188
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
189
|
+
|
|
190
|
+
// 4) reattach listeners to the new instances
|
|
191
|
+
reassignListeners(self.chat, savedChatListeners);
|
|
192
|
+
reassignListeners(self.webrtc, savedWebRTCListeners);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
resolve(); // init completed (with or without migration)
|
|
196
|
+
});
|
|
136
197
|
});
|
|
198
|
+
//
|
|
199
|
+
// previous version with callback
|
|
200
|
+
// this.service.ajax({
|
|
201
|
+
// url: accountSettingsUrl
|
|
202
|
+
// }, function (err, response) {
|
|
203
|
+
// if (!err && typeof response === 'object') {
|
|
204
|
+
// var update = {
|
|
205
|
+
// endpoints: {
|
|
206
|
+
// api: response.api_endpoint.replace(/^https?:\/\//, ''),
|
|
207
|
+
// chat: response.chat_endpoint
|
|
208
|
+
// }
|
|
209
|
+
// };
|
|
210
|
+
// config.set(update);
|
|
211
|
+
// //
|
|
212
|
+
// self.pushnotifications = new PushNotifications(self.service);
|
|
213
|
+
// self.chat = new Chat(self.service);
|
|
214
|
+
// self.chat.dialog = new DialogProxy(self.service);
|
|
215
|
+
// self.chat.message = new MessageProxy(self.service);
|
|
216
|
+
// //
|
|
217
|
+
// if (Utils.getEnv().browser) {
|
|
218
|
+
// /** add adapter.js*/
|
|
219
|
+
// require('webrtc-adapter');
|
|
220
|
+
//
|
|
221
|
+
// /** add WebRTC API if API is avaible */
|
|
222
|
+
// if( Utils.isWebRTCAvailble() ) {
|
|
223
|
+
// var WebRTCClient = require('./modules/webrtc/qbWebRTCClient');
|
|
224
|
+
// self.webrtc = new WebRTCClient(self.service, self.chat);
|
|
225
|
+
// } else {
|
|
226
|
+
// self.webrtc = false;
|
|
227
|
+
// }
|
|
228
|
+
// } else {
|
|
229
|
+
// self.webrtc = false;
|
|
230
|
+
// }
|
|
231
|
+
// //
|
|
232
|
+
// }
|
|
233
|
+
// });
|
|
234
|
+
//
|
|
137
235
|
}
|
|
236
|
+
//
|
|
237
|
+
// --- artificial sync delay to increase the chance account_settings completes before legacy code continues
|
|
238
|
+
// enabled only when shouldGetSettings && config.initBlockOnSettings !== false
|
|
239
|
+
if (shouldGetSettings && initBlockOnSettings) {
|
|
240
|
+
try {
|
|
241
|
+
var __qb_init_block_until__ = Date.now() + initBlockDurationMs;
|
|
242
|
+
while (Date.now() < __qb_init_block_until__) {
|
|
243
|
+
// intentional busy-wait (do not remove)
|
|
244
|
+
}
|
|
245
|
+
} catch (_) { /* never throw from here */ }
|
|
246
|
+
}
|
|
247
|
+
//
|
|
248
|
+
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Wait until SDK async initialization finishes (if any).
|
|
253
|
+
* It resolves after internal tasks like fetching `account_settings`,
|
|
254
|
+
* rebinding endpoints, and re-instantiating dependent modules are completed.
|
|
255
|
+
* If no async work was scheduled during `QB.init(...)`, it resolves immediately.
|
|
256
|
+
*
|
|
257
|
+
* @memberof QB
|
|
258
|
+
* @returns {Promise<void>} A promise that resolves when initialization is complete.
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* QB.init(appId, authKey, authSecret, accountKey, config);
|
|
262
|
+
* QB.ready().then(function () {
|
|
263
|
+
* // Safe point: endpoints are updated, chat/webrtc are re-created, listeners preserved.
|
|
264
|
+
* QB.startSession({ login: 'john', password: 'secret' }, function (err, res) {
|
|
265
|
+
* if (!err) {
|
|
266
|
+
* QB.chat.connect({ userId: res.user.id, password: res.session.token }, function(){});
|
|
267
|
+
* }
|
|
268
|
+
* });
|
|
269
|
+
* });
|
|
270
|
+
*/
|
|
271
|
+
ready: function() {
|
|
272
|
+
return this._initReady || Promise.resolve();
|
|
138
273
|
},
|
|
139
274
|
|
|
140
275
|
/**
|
package/src/qbProxy.js
CHANGED
|
@@ -276,13 +276,58 @@ ServiceProxy.prototype = {
|
|
|
276
276
|
|
|
277
277
|
self.handleResponse(null, body, callback, retry);
|
|
278
278
|
}
|
|
279
|
+
// if (self._fetchingSettings) {
|
|
280
|
+
// self._fetchingSettings = false;
|
|
281
|
+
// while (self._queue.length) {
|
|
282
|
+
// var args = self._queue.shift();
|
|
283
|
+
// self.ajax.apply(self, args);
|
|
284
|
+
// }
|
|
285
|
+
// }
|
|
286
|
+
//
|
|
279
287
|
if (self._fetchingSettings) {
|
|
280
288
|
self._fetchingSettings = false;
|
|
289
|
+
|
|
290
|
+
var sharedApiHost = 'api.quickblox.com';
|
|
291
|
+
var sharedChatHost = 'chat.quickblox.com';
|
|
292
|
+
|
|
293
|
+
sharedApiHost = sharedApiHost.replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
294
|
+
sharedChatHost = sharedChatHost.replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
295
|
+
|
|
296
|
+
var RE_SHARED_API = new RegExp('^https?://' + sharedApiHost.replace(/\./g, '\\.') + '(?=[:/]|$)', 'i');
|
|
297
|
+
var RE_SHARED_CHAT = new RegExp('^https?://' + sharedChatHost.replace(/\./g, '\\.') + '(?=[:/]|$)', 'i');
|
|
298
|
+
|
|
299
|
+
var newApiHost = (self.qbInst.config.endpoints.api || '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
300
|
+
var newChatHost = (self.qbInst.config.endpoints.chat || '').replace(/^https?:\/\//i, '').replace(/\/+$/, '');
|
|
301
|
+
var NEW_API_URL = 'https://' + newApiHost;
|
|
302
|
+
var NEW_CHAT_URL = 'https://' + newChatHost;
|
|
303
|
+
|
|
281
304
|
while (self._queue.length) {
|
|
282
|
-
var args = self._queue.shift();
|
|
305
|
+
var args = self._queue.shift(); // [params, callback]
|
|
306
|
+
var p = args && args[0];
|
|
307
|
+
|
|
308
|
+
if (p && typeof p.url === 'string') {
|
|
309
|
+
var url = p.url;
|
|
310
|
+
var changed = false;
|
|
311
|
+
|
|
312
|
+
if (RE_SHARED_API.test(url)) {
|
|
313
|
+
url = url.replace(RE_SHARED_API, NEW_API_URL);
|
|
314
|
+
changed = true;
|
|
315
|
+
}
|
|
316
|
+
if (RE_SHARED_CHAT.test(url)) {
|
|
317
|
+
url = url.replace(RE_SHARED_CHAT, NEW_CHAT_URL);
|
|
318
|
+
changed = true;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (changed) {
|
|
322
|
+
p.url = url;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
283
326
|
self.ajax.apply(self, args);
|
|
284
327
|
}
|
|
285
328
|
}
|
|
329
|
+
|
|
330
|
+
//
|
|
286
331
|
}
|
|
287
332
|
|
|
288
333
|
function retry(session) {
|
package/src/qbUtils.js
CHANGED
|
@@ -171,9 +171,68 @@ var Utils = {
|
|
|
171
171
|
},
|
|
172
172
|
|
|
173
173
|
QBLog: function(){
|
|
174
|
+
var argsArr = Array.prototype.slice.call(arguments);
|
|
175
|
+
|
|
176
|
+
function containsPing(x) {
|
|
177
|
+
var needle = 'ping';
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
if (x == null) return false;
|
|
181
|
+
|
|
182
|
+
if (typeof x === 'string') {
|
|
183
|
+
return x.toLowerCase().indexOf(needle) !== -1;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (typeof x === 'number' || typeof x === 'boolean') {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (typeof x === 'object') {
|
|
191
|
+
//DELETE XEP-0198 SM packages from log:
|
|
192
|
+
// <r xmlns="urn:xmpp:sm:3"/> and <a xmlns="urn:xmpp:sm:3" h="..."/>
|
|
193
|
+
if (typeof x.outerHTML === 'string') {
|
|
194
|
+
var oh = x.outerHTML.replace(/\s+/g, ' ').toLowerCase();
|
|
195
|
+
if (
|
|
196
|
+
oh.indexOf('urn:xmpp:sm:3') !== -1 &&
|
|
197
|
+
(/^<\s*r\b/.test(oh) || /^<\s*a\b/.test(oh))
|
|
198
|
+
) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
var candidates = [
|
|
204
|
+
x.textContent,
|
|
205
|
+
x.innerHTML,
|
|
206
|
+
x.outerHTML,
|
|
207
|
+
x.nodeName,
|
|
208
|
+
x.tagName,
|
|
209
|
+
x.id
|
|
210
|
+
];
|
|
211
|
+
|
|
212
|
+
for (var j = 0; j < candidates.length; j++) {
|
|
213
|
+
var s = candidates[j];
|
|
214
|
+
if (typeof s === 'string' && s.toLowerCase().indexOf(needle) !== -1) {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
} catch (_) {}
|
|
220
|
+
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
let shouldSuppressPing1 =
|
|
226
|
+
config && config.pingDebug === false;
|
|
227
|
+
let shouldSuppressPing2 =argsArr.some(containsPing);
|
|
228
|
+
|
|
229
|
+
let shouldSuppressPing = shouldSuppressPing1 && shouldSuppressPing2;
|
|
230
|
+
|
|
174
231
|
if (this.loggers) {
|
|
175
232
|
for (var i=0; i<this.loggers.length; ++i) {
|
|
176
|
-
|
|
233
|
+
if (!shouldSuppressPing) {
|
|
234
|
+
this.loggers[i](arguments);
|
|
235
|
+
}
|
|
177
236
|
}
|
|
178
237
|
|
|
179
238
|
return;
|
|
@@ -254,7 +313,12 @@ var Utils = {
|
|
|
254
313
|
|
|
255
314
|
if(this.loggers){
|
|
256
315
|
for(var j=0;j<this.loggers.length;++j){
|
|
257
|
-
this.loggers[j](arguments);
|
|
316
|
+
// this.loggers[j](arguments);
|
|
317
|
+
//
|
|
318
|
+
if (!shouldSuppressPing) {
|
|
319
|
+
this.loggers[j](arguments);
|
|
320
|
+
}
|
|
321
|
+
//
|
|
258
322
|
}
|
|
259
323
|
}
|
|
260
324
|
},
|