centrifuge 5.3.0 → 5.3.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/README.md +3 -3
- package/build/centrifuge.d.ts +1 -0
- package/build/index.js +166 -112
- package/build/index.mjs +166 -112
- package/build/protobuf/centrifuge.d.ts +1 -0
- package/build/protobuf/index.js +443 -366
- package/build/protobuf/index.mjs +443 -366
- package/build/protobuf/subscription.d.ts +9 -0
- package/build/subscription.d.ts +9 -0
- package/dist/centrifuge.js +6 -6
- package/dist/centrifuge.js.map +3 -3
- package/dist/centrifuge.protobuf.js +4 -4
- package/dist/centrifuge.protobuf.js.map +3 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ This SDK provides a client to connect to [Centrifugo](https://github.com/centrif
|
|
|
5
5
|
|
|
6
6
|
The features implemented by this SDK can be found in [SDK feature matrix](https://centrifugal.dev/docs/transports/client_sdk#sdk-feature-matrix).
|
|
7
7
|
|
|
8
|
-
> `centrifuge-js` v5.x is compatible with [Centrifugo](https://github.com/centrifugal/centrifugo) server
|
|
8
|
+
> `centrifuge-js` v5.x is compatible with [Centrifugo](https://github.com/centrifugal/centrifugo) server v6, v5 and v4, and [Centrifuge](https://github.com/centrifugal/centrifuge) >= 0.25.0. For Centrifugo v2, Centrifugo v3 and Centrifuge < 0.25.0 you should use `centrifuge-js` v2.x.
|
|
9
9
|
|
|
10
10
|
* [Install](#install)
|
|
11
11
|
* [Quick start](#quick-start)
|
|
@@ -131,14 +131,14 @@ Supported transports are:
|
|
|
131
131
|
* `websocket`
|
|
132
132
|
* `http_stream`
|
|
133
133
|
* `sse`
|
|
134
|
-
* `sockjs` - SockJS can also be used as a fallback, SockJS
|
|
134
|
+
* `sockjs` - SockJS can also be used as a fallback in Centrifugo < v6, in Centrifugo v6 SockJS was removed and will be removed in `centrifuge-js` v6 too. Also, sticky sessions must be used on the backend in distributed case with it. See more details below
|
|
135
135
|
* `webtransport` - this SDK also supports WebTransport in experimental form. See details below
|
|
136
136
|
|
|
137
137
|
If you want to use sticky sessions on a load balancer level as an optimimization for Centrifugal bidirectional emulation layer keep in mind that we currently use `same-origin` credentials policy for emulation requests in `http_stream` and `sse` transport cases. So cookies will only be passed in same-origin case. Please open an issue in case you need to configure more relaxed credentials. Though in most cases stickyness based on client's IP may be sufficient enough.
|
|
138
138
|
|
|
139
139
|
### Using SockJS
|
|
140
140
|
|
|
141
|
-
**SockJS usage is DEPRECATED in
|
|
141
|
+
**SockJS usage is DEPRECATED**. Its support was removed in Centrifugo v6, and it will also be removed from this SDK in v6 release.
|
|
142
142
|
|
|
143
143
|
If you want to use SockJS you must also import SockJS client before centrifuge.js
|
|
144
144
|
|
package/build/centrifuge.d.ts
CHANGED
|
@@ -112,6 +112,7 @@ export declare class Centrifuge extends Centrifuge_base {
|
|
|
112
112
|
private _initializeTransport;
|
|
113
113
|
private _sendConnect;
|
|
114
114
|
private _startReconnecting;
|
|
115
|
+
private _handleGetDataError;
|
|
115
116
|
private _connectError;
|
|
116
117
|
private _scheduleReconnect;
|
|
117
118
|
private _constructConnectCommand;
|
package/build/index.js
CHANGED
|
@@ -651,12 +651,10 @@ class Subscription extends EventEmitter$1 {
|
|
|
651
651
|
// @ts-ignore – we are hiding some symbols from public API autocompletion.
|
|
652
652
|
if (this._centrifuge._debugEnabled) {
|
|
653
653
|
this.on('state', (ctx) => {
|
|
654
|
-
|
|
655
|
-
this._centrifuge._debug('subscription state', channel, ctx.oldState, '->', ctx.newState);
|
|
654
|
+
this._debug('subscription state', channel, ctx.oldState, '->', ctx.newState);
|
|
656
655
|
});
|
|
657
656
|
this.on('error', (ctx) => {
|
|
658
|
-
|
|
659
|
-
this._centrifuge._debug('subscription error', channel, ctx);
|
|
657
|
+
this._debug('subscription error', channel, ctx);
|
|
660
658
|
});
|
|
661
659
|
}
|
|
662
660
|
else {
|
|
@@ -837,119 +835,121 @@ class Subscription extends EventEmitter$1 {
|
|
|
837
835
|
});
|
|
838
836
|
}
|
|
839
837
|
_subscribe() {
|
|
838
|
+
this._debug('subscribing on', this.channel);
|
|
839
|
+
if (!this._isTransportOpen()) {
|
|
840
|
+
this._debug('delay subscribe on', this.channel, 'till connected');
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
if (this._inflight) {
|
|
844
|
+
return null;
|
|
845
|
+
}
|
|
846
|
+
this._inflight = true;
|
|
847
|
+
if (this._canSubscribeWithoutGettingToken()) {
|
|
848
|
+
return this._subscribeWithoutToken();
|
|
849
|
+
}
|
|
850
|
+
this._getSubscriptionToken()
|
|
851
|
+
.then(token => this._handleTokenResponse(token))
|
|
852
|
+
.catch(e => this._handleTokenError(e));
|
|
853
|
+
return null;
|
|
854
|
+
}
|
|
855
|
+
_isTransportOpen() {
|
|
840
856
|
// @ts-ignore – we are hiding some symbols from public API autocompletion.
|
|
841
|
-
this._centrifuge.
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
857
|
+
return this._centrifuge._transportIsOpen;
|
|
858
|
+
}
|
|
859
|
+
_canSubscribeWithoutGettingToken() {
|
|
860
|
+
return !this._usesToken() || !!this._token;
|
|
861
|
+
}
|
|
862
|
+
_subscribeWithoutToken() {
|
|
863
|
+
if (this._getData) {
|
|
864
|
+
this._getDataAndSubscribe(this._token);
|
|
849
865
|
return null;
|
|
850
866
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
channel: self.channel
|
|
854
|
-
};
|
|
855
|
-
if (!this._usesToken() || this._token) {
|
|
856
|
-
if (self._getData) {
|
|
857
|
-
self._getData(getDataCtx).then(function (data) {
|
|
858
|
-
if (!self._isSubscribing()) {
|
|
859
|
-
return;
|
|
860
|
-
}
|
|
861
|
-
self._data = data;
|
|
862
|
-
self._sendSubscribe(self._token);
|
|
863
|
-
});
|
|
864
|
-
return null;
|
|
865
|
-
}
|
|
866
|
-
else {
|
|
867
|
-
return self._sendSubscribe(self._token);
|
|
868
|
-
}
|
|
867
|
+
else {
|
|
868
|
+
return this._sendSubscribe(this._token);
|
|
869
869
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
self._getData(getDataCtx).then(function (data) {
|
|
881
|
-
if (!self._isSubscribing()) {
|
|
882
|
-
return;
|
|
883
|
-
}
|
|
884
|
-
self._data = data;
|
|
885
|
-
self._sendSubscribe(token);
|
|
886
|
-
});
|
|
887
|
-
}
|
|
888
|
-
else {
|
|
889
|
-
self._sendSubscribe(token);
|
|
890
|
-
}
|
|
891
|
-
}).catch(function (e) {
|
|
892
|
-
if (!self._isSubscribing()) {
|
|
870
|
+
}
|
|
871
|
+
_getDataAndSubscribe(token) {
|
|
872
|
+
if (!this._getData) {
|
|
873
|
+
this._inflight = false;
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
this._getData({ channel: this.channel })
|
|
877
|
+
.then(data => {
|
|
878
|
+
if (!this._isSubscribing()) {
|
|
879
|
+
this._inflight = false;
|
|
893
880
|
return;
|
|
894
881
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
882
|
+
this._data = data;
|
|
883
|
+
this._sendSubscribe(token);
|
|
884
|
+
})
|
|
885
|
+
.catch(e => this._handleGetDataError(e));
|
|
886
|
+
}
|
|
887
|
+
_handleGetDataError(error) {
|
|
888
|
+
if (!this._isSubscribing()) {
|
|
889
|
+
this._inflight = false;
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
if (error instanceof UnauthorizedError) {
|
|
893
|
+
this._inflight = false;
|
|
894
|
+
this._failUnauthorized();
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
this.emit('error', {
|
|
898
|
+
type: 'subscribeData',
|
|
899
|
+
channel: this.channel,
|
|
900
|
+
error: {
|
|
901
|
+
code: exports.errorCodes.badConfiguration,
|
|
902
|
+
message: (error === null || error === void 0 ? void 0 : error.toString()) || ''
|
|
898
903
|
}
|
|
899
|
-
self.emit('error', {
|
|
900
|
-
type: 'subscribeToken',
|
|
901
|
-
channel: self.channel,
|
|
902
|
-
error: {
|
|
903
|
-
code: exports.errorCodes.subscriptionSubscribeToken,
|
|
904
|
-
message: e !== undefined ? e.toString() : ''
|
|
905
|
-
}
|
|
906
|
-
});
|
|
907
|
-
self._scheduleResubscribe();
|
|
908
904
|
});
|
|
909
|
-
|
|
905
|
+
this._inflight = false;
|
|
906
|
+
this._scheduleResubscribe();
|
|
910
907
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
if (!this._centrifuge._transportIsOpen) {
|
|
916
|
-
return null;
|
|
908
|
+
_handleTokenResponse(token) {
|
|
909
|
+
if (!this._isSubscribing()) {
|
|
910
|
+
this._inflight = false;
|
|
911
|
+
return;
|
|
917
912
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
if (token) {
|
|
923
|
-
req.token = token;
|
|
913
|
+
if (!token) {
|
|
914
|
+
this._inflight = false;
|
|
915
|
+
this._failUnauthorized();
|
|
916
|
+
return;
|
|
924
917
|
}
|
|
925
|
-
|
|
926
|
-
|
|
918
|
+
this._token = token;
|
|
919
|
+
if (this._getData) {
|
|
920
|
+
this._getDataAndSubscribe(token);
|
|
927
921
|
}
|
|
928
|
-
|
|
929
|
-
|
|
922
|
+
else {
|
|
923
|
+
this._sendSubscribe(token);
|
|
930
924
|
}
|
|
931
|
-
|
|
932
|
-
|
|
925
|
+
}
|
|
926
|
+
_handleTokenError(error) {
|
|
927
|
+
if (!this._isSubscribing()) {
|
|
928
|
+
this._inflight = false;
|
|
929
|
+
return;
|
|
933
930
|
}
|
|
934
|
-
if (
|
|
935
|
-
|
|
931
|
+
if (error instanceof UnauthorizedError) {
|
|
932
|
+
this._inflight = false;
|
|
933
|
+
this._failUnauthorized();
|
|
934
|
+
return;
|
|
936
935
|
}
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
936
|
+
this.emit('error', {
|
|
937
|
+
type: 'subscribeToken',
|
|
938
|
+
channel: this.channel,
|
|
939
|
+
error: {
|
|
940
|
+
code: exports.errorCodes.subscriptionSubscribeToken,
|
|
941
|
+
message: (error === null || error === void 0 ? void 0 : error.toString()) || ''
|
|
942
942
|
}
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
if (this.
|
|
949
|
-
|
|
943
|
+
});
|
|
944
|
+
this._inflight = false;
|
|
945
|
+
this._scheduleResubscribe();
|
|
946
|
+
}
|
|
947
|
+
_sendSubscribe(token) {
|
|
948
|
+
if (!this._isTransportOpen()) {
|
|
949
|
+
this._inflight = false;
|
|
950
|
+
return null;
|
|
950
951
|
}
|
|
951
|
-
const cmd =
|
|
952
|
-
this._inflight = true;
|
|
952
|
+
const cmd = this._buildSubscribeCommand(token);
|
|
953
953
|
// @ts-ignore – we are hiding some symbols from public API autocompletion.
|
|
954
954
|
this._centrifuge._call(cmd).then(resolveCtx => {
|
|
955
955
|
this._inflight = false;
|
|
@@ -970,6 +970,35 @@ class Subscription extends EventEmitter$1 {
|
|
|
970
970
|
});
|
|
971
971
|
return cmd;
|
|
972
972
|
}
|
|
973
|
+
_buildSubscribeCommand(token) {
|
|
974
|
+
const req = { channel: this.channel };
|
|
975
|
+
if (token)
|
|
976
|
+
req.token = token;
|
|
977
|
+
if (this._data)
|
|
978
|
+
req.data = this._data;
|
|
979
|
+
if (this._positioned)
|
|
980
|
+
req.positioned = true;
|
|
981
|
+
if (this._recoverable)
|
|
982
|
+
req.recoverable = true;
|
|
983
|
+
if (this._joinLeave)
|
|
984
|
+
req.join_leave = true;
|
|
985
|
+
if (this._needRecover()) {
|
|
986
|
+
req.recover = true;
|
|
987
|
+
const offset = this._getOffset();
|
|
988
|
+
if (offset)
|
|
989
|
+
req.offset = offset;
|
|
990
|
+
const epoch = this._getEpoch();
|
|
991
|
+
if (epoch)
|
|
992
|
+
req.epoch = epoch;
|
|
993
|
+
}
|
|
994
|
+
if (this._delta)
|
|
995
|
+
req.delta = this._delta;
|
|
996
|
+
return { subscribe: req };
|
|
997
|
+
}
|
|
998
|
+
_debug(...args) {
|
|
999
|
+
// @ts-ignore – we are hiding some symbols from public API autocompletion.
|
|
1000
|
+
this._centrifuge._debug(...args);
|
|
1001
|
+
}
|
|
973
1002
|
_handleSubscribeError(error) {
|
|
974
1003
|
if (!this._isSubscribing()) {
|
|
975
1004
|
return;
|
|
@@ -1006,6 +1035,7 @@ class Subscription extends EventEmitter$1 {
|
|
|
1006
1035
|
}
|
|
1007
1036
|
this._clearSubscribingState();
|
|
1008
1037
|
}
|
|
1038
|
+
this._inflight = false;
|
|
1009
1039
|
if (this._setState(exports.SubscriptionState.Unsubscribed)) {
|
|
1010
1040
|
this.emit('unsubscribed', { channel: this.channel, code: code, reason: reason });
|
|
1011
1041
|
}
|
|
@@ -1061,6 +1091,10 @@ class Subscription extends EventEmitter$1 {
|
|
|
1061
1091
|
}
|
|
1062
1092
|
}
|
|
1063
1093
|
_scheduleResubscribe() {
|
|
1094
|
+
if (!this._isSubscribing()) {
|
|
1095
|
+
this._debug('not in subscribing state, skip resubscribe scheduling', this.channel);
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1064
1098
|
const self = this;
|
|
1065
1099
|
const delay = this._getResubscribeDelay();
|
|
1066
1100
|
this._resubscribeTimeout = setTimeout(function () {
|
|
@@ -1068,6 +1102,7 @@ class Subscription extends EventEmitter$1 {
|
|
|
1068
1102
|
self._subscribe();
|
|
1069
1103
|
}
|
|
1070
1104
|
}, delay);
|
|
1105
|
+
this._debug('resubscribe scheduled after ' + delay, this.channel);
|
|
1071
1106
|
}
|
|
1072
1107
|
_subscribeError(err) {
|
|
1073
1108
|
if (!this._isSubscribing()) {
|
|
@@ -1166,8 +1201,7 @@ class Subscription extends EventEmitter$1 {
|
|
|
1166
1201
|
}
|
|
1167
1202
|
}
|
|
1168
1203
|
_getSubscriptionToken() {
|
|
1169
|
-
|
|
1170
|
-
this._centrifuge._debug('get subscription token for channel', this.channel);
|
|
1204
|
+
this._debug('get subscription token for channel', this.channel);
|
|
1171
1205
|
const ctx = {
|
|
1172
1206
|
channel: this.channel
|
|
1173
1207
|
};
|
|
@@ -1240,8 +1274,7 @@ class Subscription extends EventEmitter$1 {
|
|
|
1240
1274
|
if (!this._isSubscribed()) {
|
|
1241
1275
|
return;
|
|
1242
1276
|
}
|
|
1243
|
-
|
|
1244
|
-
this._centrifuge._debug('subscription token refreshed, channel', this.channel);
|
|
1277
|
+
this._debug('subscription token refreshed, channel', this.channel);
|
|
1245
1278
|
this._clearRefreshTimeout();
|
|
1246
1279
|
if (result.expires === true) {
|
|
1247
1280
|
this._refreshTimeout = setTimeout(() => this._refresh(), ttlMilliseconds(result.ttl));
|
|
@@ -2803,24 +2836,25 @@ class Centrifuge extends EventEmitter$1 {
|
|
|
2803
2836
|
return;
|
|
2804
2837
|
}
|
|
2805
2838
|
this._reconnecting = true;
|
|
2806
|
-
const self = this;
|
|
2807
2839
|
const emptyToken = this._token === '';
|
|
2808
2840
|
const needTokenRefresh = this._refreshRequired || (emptyToken && this._config.getToken !== null);
|
|
2809
2841
|
if (!needTokenRefresh) {
|
|
2810
2842
|
if (this._config.getData) {
|
|
2811
|
-
this._config.getData().then(
|
|
2812
|
-
if (!
|
|
2843
|
+
this._config.getData().then(data => {
|
|
2844
|
+
if (!this._isConnecting()) {
|
|
2813
2845
|
return;
|
|
2814
2846
|
}
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
})
|
|
2847
|
+
this._data = data;
|
|
2848
|
+
this._initializeTransport();
|
|
2849
|
+
})
|
|
2850
|
+
.catch(e => this._handleGetDataError(e));
|
|
2818
2851
|
}
|
|
2819
2852
|
else {
|
|
2820
2853
|
this._initializeTransport();
|
|
2821
2854
|
}
|
|
2822
2855
|
return;
|
|
2823
2856
|
}
|
|
2857
|
+
const self = this;
|
|
2824
2858
|
this._getToken().then(function (token) {
|
|
2825
2859
|
if (!self._isConnecting()) {
|
|
2826
2860
|
return;
|
|
@@ -2838,7 +2872,8 @@ class Centrifuge extends EventEmitter$1 {
|
|
|
2838
2872
|
}
|
|
2839
2873
|
self._data = data;
|
|
2840
2874
|
self._initializeTransport();
|
|
2841
|
-
})
|
|
2875
|
+
})
|
|
2876
|
+
.catch(e => self._handleGetDataError(e));
|
|
2842
2877
|
}
|
|
2843
2878
|
else {
|
|
2844
2879
|
self._initializeTransport();
|
|
@@ -2859,13 +2894,32 @@ class Centrifuge extends EventEmitter$1 {
|
|
|
2859
2894
|
}
|
|
2860
2895
|
});
|
|
2861
2896
|
const delay = self._getReconnectDelay();
|
|
2862
|
-
self._debug('error on connection token
|
|
2897
|
+
self._debug('error on getting connection token, reconnect after ' + delay + ' milliseconds', e);
|
|
2863
2898
|
self._reconnecting = false;
|
|
2864
2899
|
self._reconnectTimeout = setTimeout(() => {
|
|
2865
2900
|
self._startReconnecting();
|
|
2866
2901
|
}, delay);
|
|
2867
2902
|
});
|
|
2868
2903
|
}
|
|
2904
|
+
_handleGetDataError(e) {
|
|
2905
|
+
if (e instanceof UnauthorizedError) {
|
|
2906
|
+
this._failUnauthorized();
|
|
2907
|
+
return;
|
|
2908
|
+
}
|
|
2909
|
+
this.emit('error', {
|
|
2910
|
+
type: 'connectData',
|
|
2911
|
+
error: {
|
|
2912
|
+
code: exports.errorCodes.badConfiguration,
|
|
2913
|
+
message: (e === null || e === void 0 ? void 0 : e.toString()) || ''
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2916
|
+
const delay = this._getReconnectDelay();
|
|
2917
|
+
this._debug('error on getting connect data, reconnect after ' + delay + ' milliseconds', e);
|
|
2918
|
+
this._reconnecting = false;
|
|
2919
|
+
this._reconnectTimeout = setTimeout(() => {
|
|
2920
|
+
this._startReconnecting();
|
|
2921
|
+
}, delay);
|
|
2922
|
+
}
|
|
2869
2923
|
_connectError(err) {
|
|
2870
2924
|
if (this.state !== exports.State.Connecting) {
|
|
2871
2925
|
return;
|