centrifuge 5.3.5 → 5.4.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.
package/README.md CHANGED
@@ -28,6 +28,7 @@ The features implemented by this SDK can be found in [SDK feature matrix](https:
28
28
  * [Using with NodeJS](#using-with-nodejs)
29
29
  * [Custom WebSocket constructor](#custom-websocket-constructor)
30
30
  * [Using with React Native on Android](#using-with-react-native-on-android)
31
+ * [Errors in callbacks](#errors-in-callbacks)
31
32
  * [Run tests locally](#run-tests-locally)
32
33
 
33
34
  ## Install
@@ -822,6 +823,10 @@ See a basic example with React Native where this technique is used [in this comm
822
823
 
823
824
  If you have issues with the connection on Android when using React Native – [check out this comment](https://github.com/centrifugal/centrifuge-js/issues/242#issuecomment-2569474401) – you may be using non-secure endpoint schemes and need to explicitly allow it.
824
825
 
826
+ ## Errors in callbacks
827
+
828
+ There is currently no built-in error handling in the SDK for exceptions happening in application-level callbacks, which means you must catch any error that could be thrown in a listener. Not doing that may corrupt a state of SDK making it unusable.
829
+
825
830
  ## Run tests locally
826
831
 
827
832
  If you want to run `centrifuge-js` tests locally, start test Centrifugo server:
@@ -87,7 +87,6 @@ export declare class Centrifuge extends Centrifuge_base {
87
87
  history(channel: string, options?: HistoryOptions): Promise<HistoryResult>;
88
88
  /** presence for a channel. */
89
89
  presence(channel: string): Promise<PresenceResult>;
90
- /** presence stats for a channel. */
91
90
  presenceStats(channel: string): Promise<PresenceStatsResult>;
92
91
  /** start command batching (collect into temporary buffer without sending to a server)
93
92
  * until stopBatching called.*/
@@ -96,6 +95,7 @@ export declare class Centrifuge extends Centrifuge_base {
96
95
  * network (all in one request/frame).*/
97
96
  stopBatching(): void;
98
97
  private _debug;
98
+ private _codecName;
99
99
  private _configure;
100
100
  private _setState;
101
101
  private _isDisconnected;
package/build/index.js CHANGED
@@ -699,31 +699,31 @@ class Subscription extends EventEmitter$1 {
699
699
  }
700
700
  /** publish data to a channel.*/
701
701
  publish(data) {
702
- const self = this;
703
- return this._methodCall().then(function () {
704
- return self._centrifuge.publish(self.channel, data);
702
+ return __awaiter(this, void 0, void 0, function* () {
703
+ yield this._methodCall();
704
+ return this._centrifuge.publish(this.channel, data);
705
705
  });
706
706
  }
707
707
  /** get online presence for a channel.*/
708
708
  presence() {
709
- const self = this;
710
- return this._methodCall().then(function () {
711
- return self._centrifuge.presence(self.channel);
709
+ return __awaiter(this, void 0, void 0, function* () {
710
+ yield this._methodCall();
711
+ return this._centrifuge.presence(this.channel);
712
712
  });
713
713
  }
714
714
  /** presence stats for a channel (num clients and unique users).*/
715
715
  presenceStats() {
716
- const self = this;
717
- return this._methodCall().then(function () {
718
- return self._centrifuge.presenceStats(self.channel);
716
+ return __awaiter(this, void 0, void 0, function* () {
717
+ yield this._methodCall();
718
+ return this._centrifuge.presenceStats(this.channel);
719
719
  });
720
720
  }
721
721
  /** history for a channel. By default it does not return publications (only current
722
722
  * StreamPosition data) – provide an explicit limit > 0 to load publications.*/
723
723
  history(opts) {
724
- const self = this;
725
- return this._methodCall().then(function () {
726
- return self._centrifuge.history(self.channel, opts);
724
+ return __awaiter(this, void 0, void 0, function* () {
725
+ yield this._methodCall();
726
+ return this._centrifuge.history(this.channel, opts);
727
727
  });
728
728
  }
729
729
  _methodCall() {
@@ -731,17 +731,21 @@ class Subscription extends EventEmitter$1 {
731
731
  return Promise.resolve();
732
732
  }
733
733
  if (this._isUnsubscribed()) {
734
- return Promise.reject({ code: exports.errorCodes.subscriptionUnsubscribed, message: this.state });
734
+ return Promise.reject({
735
+ code: exports.errorCodes.subscriptionUnsubscribed,
736
+ message: this.state
737
+ });
735
738
  }
736
- return new Promise((res, rej) => {
737
- const timeout = setTimeout(function () {
738
- rej({ code: exports.errorCodes.timeout, message: 'timeout' });
739
- // @ts-ignore we are hiding some symbols from public API autocompletion.
740
- }, this._centrifuge._config.timeout);
739
+ return new Promise((resolve, reject) => {
740
+ // @ts-ignore we are hiding some symbols from public API autocompletion.
741
+ const timeoutDuration = this._centrifuge._config.timeout;
742
+ const timeout = setTimeout(() => {
743
+ reject({ code: exports.errorCodes.timeout, message: 'timeout' });
744
+ }, timeoutDuration);
741
745
  this._promises[this._nextPromiseId()] = {
742
- timeout: timeout,
743
- resolve: res,
744
- reject: rej
746
+ timeout,
747
+ resolve,
748
+ reject
745
749
  };
746
750
  });
747
751
  }
@@ -953,12 +957,9 @@ class Subscription extends EventEmitter$1 {
953
957
  // @ts-ignore – we are hiding some symbols from public API autocompletion.
954
958
  this._centrifuge._call(cmd).then(resolveCtx => {
955
959
  this._inflight = false;
956
- // @ts-ignore - improve later.
957
960
  const result = resolveCtx.reply.subscribe;
958
961
  this._handleSubscribeResponse(result);
959
- // @ts-ignore - improve later.
960
962
  if (resolveCtx.next) {
961
- // @ts-ignore - improve later.
962
963
  resolveCtx.next();
963
964
  }
964
965
  }, rejectCtx => {
@@ -1240,12 +1241,9 @@ class Subscription extends EventEmitter$1 {
1240
1241
  };
1241
1242
  // @ts-ignore – we are hiding some symbols from public API autocompletion.
1242
1243
  self._centrifuge._call(msg).then(resolveCtx => {
1243
- // @ts-ignore - improve later.
1244
1244
  const result = resolveCtx.reply.sub_refresh;
1245
1245
  self._refreshResponse(result);
1246
- // @ts-ignore - improve later.
1247
1246
  if (resolveCtx.next) {
1248
- // @ts-ignore - improve later.
1249
1247
  resolveCtx.next();
1250
1248
  }
1251
1249
  }, rejectCtx => {
@@ -2157,24 +2155,22 @@ class Centrifuge extends EventEmitter$1 {
2157
2155
  * state and rejects in case of client goes to Disconnected or Failed state.
2158
2156
  * Users can provide optional timeout in milliseconds. */
2159
2157
  ready(timeout) {
2160
- if (this.state === exports.State.Disconnected) {
2161
- return Promise.reject({ code: exports.errorCodes.clientDisconnected, message: 'client disconnected' });
2162
- }
2163
- if (this.state === exports.State.Connected) {
2164
- return Promise.resolve();
2158
+ switch (this.state) {
2159
+ case exports.State.Disconnected:
2160
+ return Promise.reject({ code: exports.errorCodes.clientDisconnected, message: 'client disconnected' });
2161
+ case exports.State.Connected:
2162
+ return Promise.resolve();
2163
+ default:
2164
+ return new Promise((resolve, reject) => {
2165
+ const ctx = { resolve, reject };
2166
+ if (timeout) {
2167
+ ctx.timeout = setTimeout(() => {
2168
+ reject({ code: exports.errorCodes.timeout, message: 'timeout' });
2169
+ }, timeout);
2170
+ }
2171
+ this._promises[this._nextPromiseId()] = ctx;
2172
+ });
2165
2173
  }
2166
- return new Promise((res, rej) => {
2167
- const ctx = {
2168
- resolve: res,
2169
- reject: rej
2170
- };
2171
- if (timeout) {
2172
- ctx.timeout = setTimeout(function () {
2173
- rej({ code: exports.errorCodes.timeout, message: 'timeout' });
2174
- }, timeout);
2175
- }
2176
- this._promises[this._nextPromiseId()] = ctx;
2177
- });
2178
2174
  }
2179
2175
  /** connect to a server. */
2180
2176
  connect() {
@@ -2205,121 +2201,113 @@ class Centrifuge extends EventEmitter$1 {
2205
2201
  /** send asynchronous data to a server (without any response from a server
2206
2202
  * expected, see rpc method if you need response). */
2207
2203
  send(data) {
2208
- const cmd = {
2209
- send: {
2210
- data: data
2211
- }
2212
- };
2213
- const self = this;
2214
- return this._methodCall().then(function () {
2215
- const sent = self._transportSendCommands([cmd]); // can send message to server without id set
2204
+ return __awaiter(this, void 0, void 0, function* () {
2205
+ const cmd = {
2206
+ send: {
2207
+ data
2208
+ }
2209
+ };
2210
+ yield this._methodCall();
2211
+ const sent = this._transportSendCommands([cmd]); // can send message to server without id set
2216
2212
  if (!sent) {
2217
- return Promise.reject(self._createErrorObject(exports.errorCodes.transportWriteError, 'transport write error'));
2213
+ throw this._createErrorObject(exports.errorCodes.transportWriteError, 'transport write error');
2218
2214
  }
2219
- return Promise.resolve();
2220
2215
  });
2221
2216
  }
2222
2217
  /** rpc to a server - i.e. a call which waits for a response with data. */
2223
2218
  rpc(method, data) {
2224
- const cmd = {
2225
- rpc: {
2226
- method: method,
2227
- data: data
2228
- }
2229
- };
2230
- const self = this;
2231
- return this._methodCall().then(function () {
2232
- return self._callPromise(cmd, function (reply) {
2233
- return {
2234
- 'data': reply.rpc.data
2235
- };
2236
- });
2219
+ return __awaiter(this, void 0, void 0, function* () {
2220
+ const cmd = {
2221
+ rpc: {
2222
+ method,
2223
+ data
2224
+ }
2225
+ };
2226
+ yield this._methodCall();
2227
+ const result = yield this._callPromise(cmd, (reply) => reply.rpc);
2228
+ return {
2229
+ data: result.data
2230
+ };
2237
2231
  });
2238
2232
  }
2239
2233
  /** publish data to a channel. */
2240
2234
  publish(channel, data) {
2241
- const cmd = {
2242
- publish: {
2243
- channel: channel,
2244
- data: data
2245
- }
2246
- };
2247
- const self = this;
2248
- return this._methodCall().then(function () {
2249
- return self._callPromise(cmd, function () {
2250
- return {};
2251
- });
2235
+ return __awaiter(this, void 0, void 0, function* () {
2236
+ const cmd = {
2237
+ publish: {
2238
+ channel,
2239
+ data
2240
+ }
2241
+ };
2242
+ yield this._methodCall();
2243
+ yield this._callPromise(cmd, () => ({}));
2244
+ return {};
2252
2245
  });
2253
2246
  }
2254
2247
  /** history for a channel. By default it does not return publications (only current
2255
2248
  * StreamPosition data) – provide an explicit limit > 0 to load publications.*/
2256
2249
  history(channel, options) {
2257
- const cmd = {
2258
- history: this._getHistoryRequest(channel, options)
2259
- };
2260
- const self = this;
2261
- return this._methodCall().then(function () {
2262
- return self._callPromise(cmd, function (reply) {
2263
- const result = reply.history;
2264
- const publications = [];
2265
- if (result.publications) {
2266
- for (let i = 0; i < result.publications.length; i++) {
2267
- publications.push(self._getPublicationContext(channel, result.publications[i]));
2268
- }
2250
+ return __awaiter(this, void 0, void 0, function* () {
2251
+ const cmd = {
2252
+ history: this._getHistoryRequest(channel, options)
2253
+ };
2254
+ yield this._methodCall();
2255
+ const result = yield this._callPromise(cmd, (reply) => reply.history);
2256
+ const publications = [];
2257
+ if (result.publications) {
2258
+ for (let i = 0; i < result.publications.length; i++) {
2259
+ publications.push(this._getPublicationContext(channel, result.publications[i]));
2269
2260
  }
2270
- return {
2271
- 'publications': publications,
2272
- 'epoch': result.epoch || '',
2273
- 'offset': result.offset || 0
2274
- };
2275
- });
2261
+ }
2262
+ return {
2263
+ publications,
2264
+ epoch: result.epoch || '',
2265
+ offset: result.offset || 0
2266
+ };
2276
2267
  });
2277
2268
  }
2278
2269
  /** presence for a channel. */
2279
2270
  presence(channel) {
2280
- const cmd = {
2281
- presence: {
2282
- channel: channel
2283
- }
2284
- };
2285
- const self = this;
2286
- return this._methodCall().then(function () {
2287
- return self._callPromise(cmd, function (reply) {
2288
- const clients = reply.presence.presence;
2289
- for (const clientId in clients) {
2290
- if (clients.hasOwnProperty(clientId)) {
2291
- const connInfo = clients[clientId]['conn_info'];
2292
- const chanInfo = clients[clientId]['chan_info'];
2293
- if (connInfo) {
2294
- clients[clientId].connInfo = connInfo;
2295
- }
2296
- if (chanInfo) {
2297
- clients[clientId].chanInfo = chanInfo;
2298
- }
2271
+ return __awaiter(this, void 0, void 0, function* () {
2272
+ const cmd = {
2273
+ presence: {
2274
+ channel
2275
+ }
2276
+ };
2277
+ yield this._methodCall();
2278
+ const result = yield this._callPromise(cmd, (reply) => reply.presence);
2279
+ const clients = result.presence;
2280
+ for (const clientId in clients) {
2281
+ if (Object.prototype.hasOwnProperty.call(clients, clientId)) {
2282
+ const rawClient = clients[clientId];
2283
+ const connInfo = rawClient['conn_info'];
2284
+ const chanInfo = rawClient['chan_info'];
2285
+ if (connInfo) {
2286
+ rawClient.connInfo = connInfo;
2287
+ }
2288
+ if (chanInfo) {
2289
+ rawClient.chanInfo = chanInfo;
2299
2290
  }
2300
2291
  }
2301
- return {
2302
- 'clients': clients
2303
- };
2304
- });
2292
+ }
2293
+ return { clients };
2305
2294
  });
2306
2295
  }
2307
- /** presence stats for a channel. */
2308
2296
  presenceStats(channel) {
2309
- const cmd = {
2310
- 'presence_stats': {
2311
- channel: channel
2312
- }
2313
- };
2314
- const self = this;
2315
- return this._methodCall().then(function () {
2316
- return self._callPromise(cmd, function (reply) {
2317
- const result = reply.presence_stats;
2318
- return {
2319
- 'numUsers': result.num_users,
2320
- 'numClients': result.num_clients
2321
- };
2297
+ return __awaiter(this, void 0, void 0, function* () {
2298
+ const cmd = {
2299
+ 'presence_stats': {
2300
+ channel
2301
+ }
2302
+ };
2303
+ yield this._methodCall();
2304
+ const result = yield this._callPromise(cmd, (reply) => {
2305
+ return reply.presence_stats;
2322
2306
  });
2307
+ return {
2308
+ numUsers: result.num_users,
2309
+ numClients: result.num_clients
2310
+ };
2323
2311
  });
2324
2312
  }
2325
2313
  /** start command batching (collect into temporary buffer without sending to a server)
@@ -2349,6 +2337,9 @@ class Centrifuge extends EventEmitter$1 {
2349
2337
  }
2350
2338
  log('debug', args);
2351
2339
  }
2340
+ _codecName() {
2341
+ return this._codec.name();
2342
+ }
2352
2343
  /** @internal */
2353
2344
  _formatOverride() {
2354
2345
  return;
@@ -2692,7 +2683,7 @@ class Centrifuge extends EventEmitter$1 {
2692
2683
  connectTimeout = setTimeout(function () {
2693
2684
  transport.close();
2694
2685
  }, this._config.timeout);
2695
- this._transport.initialize(this._codec.name(), {
2686
+ this._transport.initialize(this._codecName(), {
2696
2687
  onOpen: function () {
2697
2688
  if (connectTimeout) {
2698
2689
  clearTimeout(connectTimeout);
@@ -2801,12 +2792,9 @@ class Centrifuge extends EventEmitter$1 {
2801
2792
  const connectCommand = this._constructConnectCommand();
2802
2793
  const self = this;
2803
2794
  this._call(connectCommand, skipSending).then(resolveCtx => {
2804
- // @ts-ignore = improve later.
2805
2795
  const result = resolveCtx.reply.connect;
2806
2796
  self._connectResponse(result);
2807
- // @ts-ignore - improve later.
2808
2797
  if (resolveCtx.next) {
2809
- // @ts-ignore - improve later.
2810
2798
  resolveCtx.next();
2811
2799
  }
2812
2800
  }, rejectCtx => {
@@ -3034,19 +3022,15 @@ class Centrifuge extends EventEmitter$1 {
3034
3022
  }
3035
3023
  _callPromise(cmd, resultCB) {
3036
3024
  return new Promise((resolve, reject) => {
3037
- this._call(cmd, false).then(resolveCtx => {
3038
- // @ts-ignore - improve later.
3039
- resolve(resultCB(resolveCtx.reply));
3040
- // @ts-ignore - improve later.
3041
- if (resolveCtx.next) {
3042
- // @ts-ignore - improve later.
3043
- resolveCtx.next();
3044
- }
3045
- }, rejectCtx => {
3025
+ this._call(cmd, false).then((resolveCtx) => {
3026
+ var _a;
3027
+ const result = resultCB(resolveCtx.reply);
3028
+ resolve(result);
3029
+ (_a = resolveCtx.next) === null || _a === void 0 ? void 0 : _a.call(resolveCtx);
3030
+ }, (rejectCtx) => {
3031
+ var _a;
3046
3032
  reject(rejectCtx.error);
3047
- if (rejectCtx.next) {
3048
- rejectCtx.next();
3049
- }
3033
+ (_a = rejectCtx.next) === null || _a === void 0 ? void 0 : _a.call(rejectCtx);
3050
3034
  });
3051
3035
  });
3052
3036
  }
@@ -3209,12 +3193,9 @@ class Centrifuge extends EventEmitter$1 {
3209
3193
  refresh: { token: self._token }
3210
3194
  };
3211
3195
  self._call(cmd, false).then(resolveCtx => {
3212
- // @ts-ignore - improve later.
3213
3196
  const result = resolveCtx.reply.refresh;
3214
3197
  self._refreshResponse(result);
3215
- // @ts-ignore - improve later.
3216
3198
  if (resolveCtx.next) {
3217
- // @ts-ignore - improve later.
3218
3199
  resolveCtx.next();
3219
3200
  }
3220
3201
  }, rejectCtx => {
@@ -3284,9 +3265,7 @@ class Centrifuge extends EventEmitter$1 {
3284
3265
  const unsubscribePromise = new Promise((resolve, _) => {
3285
3266
  this._call(cmd, false).then(resolveCtx => {
3286
3267
  resolve();
3287
- // @ts-ignore - improve later.
3288
3268
  if (resolveCtx.next) {
3289
- // @ts-ignore - improve later.
3290
3269
  resolveCtx.next();
3291
3270
  }
3292
3271
  }, rejectCtx => {
@@ -3449,7 +3428,8 @@ class Centrifuge extends EventEmitter$1 {
3449
3428
  positioned: false,
3450
3429
  recoverable: false,
3451
3430
  wasRecovering: false,
3452
- recovered: false
3431
+ recovered: false,
3432
+ hasRecoveredPublications: false,
3453
3433
  };
3454
3434
  if (result.recovered) {
3455
3435
  ctx.recovered = true;
@@ -3477,6 +3457,9 @@ class Centrifuge extends EventEmitter$1 {
3477
3457
  'epoch': epoch
3478
3458
  };
3479
3459
  }
3460
+ if (Array.isArray(result.publications) && result.publications.length > 0) {
3461
+ ctx.hasRecoveredPublications = true;
3462
+ }
3480
3463
  if (result.data) {
3481
3464
  ctx.data = result.data;
3482
3465
  }
@@ -3504,7 +3487,7 @@ class Centrifuge extends EventEmitter$1 {
3504
3487
  next();
3505
3488
  return;
3506
3489
  }
3507
- const error = reply.error;
3490
+ const error = { code: reply.error.code, message: reply.error.message || '', temporary: reply.error.temporary || false };
3508
3491
  errback({ error, next });
3509
3492
  }
3510
3493
  }
@@ -3587,11 +3570,13 @@ class Centrifuge extends EventEmitter$1 {
3587
3570
  client: clientInfo.client,
3588
3571
  user: clientInfo.user
3589
3572
  };
3590
- if (clientInfo.conn_info) {
3591
- info.connInfo = clientInfo.conn_info;
3573
+ const connInfo = clientInfo['conn_info'];
3574
+ if (connInfo) {
3575
+ info.connInfo = connInfo;
3592
3576
  }
3593
- if (clientInfo.chan_info) {
3594
- info.chanInfo = clientInfo.chan_info;
3577
+ const chanInfo = clientInfo['chan_info'];
3578
+ if (chanInfo) {
3579
+ info.chanInfo = chanInfo;
3595
3580
  }
3596
3581
  return info;
3597
3582
  }