polfan-server-js-client 0.4.2 → 0.4.4
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/.idea/shelf/Uncommitted_changes_before_Update_at_08_09_2026_17_04_[Changes]/shelved.patch +0 -0
- package/.idea/shelf/Uncommitted_changes_before_Update_at_08_09_2026_17_04__Changes_.xml +4 -0
- package/.idea/workspace.xml +49 -28
- package/README.md +20 -0
- package/build/index.cjs.js +192 -51
- package/build/index.cjs.js.map +1 -1
- package/build/index.umd.js +1 -1
- package/build/index.umd.js.map +1 -1
- package/build/types/Permissions.d.ts +4 -0
- package/build/types/WebSocketChatClient.d.ts +34 -2
- package/build/types/index.d.ts +2 -2
- package/build/types/types/src/index.d.ts +3 -3
- package/build/types/types/src/schemes/Message.d.ts +10 -0
- package/build/types/types/src/schemes/Role.d.ts +14 -0
- package/build/types/types/src/schemes/commands/CreateRole.d.ts +1 -0
- package/build/types/types/src/schemes/commands/UpdateRole.d.ts +1 -0
- package/package.json +1 -1
- package/src/Permissions.ts +1 -0
- package/src/WebSocketChatClient.ts +157 -26
- package/src/index.ts +2 -1
- package/src/types/src/index.ts +4 -2
- package/src/types/src/schemes/Message.ts +11 -0
- package/src/types/src/schemes/Role.ts +16 -1
- package/src/types/src/schemes/commands/CreateRole.ts +1 -0
- package/src/types/src/schemes/commands/UpdateRole.ts +1 -0
- package/tests/space-roles.test.ts +5 -5
- package/tests/websocket-reconnect.test.ts +408 -0
package/.idea/shelf/Uncommitted_changes_before_Update_at_08_09_2026_17_04_[Changes]/shelved.patch
ADDED
|
File without changes
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<changelist name="Uncommitted_changes_before_Update_at_08_09_2026_17_04_[Changes]" date="1788879866780" recycled="true" deleted="true">
|
|
2
|
+
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Update_at_08_09_2026_17_04_[Changes]/shelved.patch" />
|
|
3
|
+
<option name="DESCRIPTION" value="Uncommitted changes before Update at 08.09.2026 17:04 [Changes]" />
|
|
4
|
+
</changelist>
|
package/.idea/workspace.xml
CHANGED
|
@@ -4,7 +4,15 @@
|
|
|
4
4
|
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
5
|
</component>
|
|
6
6
|
<component name="ChangeListManager">
|
|
7
|
-
<list default="true" id="831dae43-0da1-47fd-a5f7-33dd5eec2992" name="Changes" comment="
|
|
7
|
+
<list default="true" id="831dae43-0da1-47fd-a5f7-33dd5eec2992" name="Changes" comment="Bump version">
|
|
8
|
+
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
|
9
|
+
<change beforePath="$PROJECT_DIR$/build/index.cjs.js" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.cjs.js" afterDir="false" />
|
|
10
|
+
<change beforePath="$PROJECT_DIR$/build/index.cjs.js.map" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.cjs.js.map" afterDir="false" />
|
|
11
|
+
<change beforePath="$PROJECT_DIR$/build/index.umd.js" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.umd.js" afterDir="false" />
|
|
12
|
+
<change beforePath="$PROJECT_DIR$/build/index.umd.js.map" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.umd.js.map" afterDir="false" />
|
|
13
|
+
<change beforePath="$PROJECT_DIR$/build/types/WebSocketChatClient.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/build/types/WebSocketChatClient.d.ts" afterDir="false" />
|
|
14
|
+
<change beforePath="$PROJECT_DIR$/src/WebSocketChatClient.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/WebSocketChatClient.ts" afterDir="false" />
|
|
15
|
+
</list>
|
|
8
16
|
<option name="SHOW_DIALOG" value="false" />
|
|
9
17
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
10
18
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
@@ -14,7 +22,7 @@
|
|
|
14
22
|
<execution />
|
|
15
23
|
</component>
|
|
16
24
|
<component name="EmbeddingIndexingInfo">
|
|
17
|
-
<option name="cachedIndexableFilesCount" value="
|
|
25
|
+
<option name="cachedIndexableFilesCount" value="223" />
|
|
18
26
|
</component>
|
|
19
27
|
<component name="Git.Rebase.Settings">
|
|
20
28
|
<option name="NEW_BASE" value="master" />
|
|
@@ -28,7 +36,7 @@
|
|
|
28
36
|
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
|
29
37
|
<map>
|
|
30
38
|
<entry key="$PROJECT_DIR$" value="claude/chat-reactions-polls-system-hwea5i" />
|
|
31
|
-
<entry key="$PROJECT_DIR$/src/types" value="
|
|
39
|
+
<entry key="$PROJECT_DIR$/src/types" value="claude/chat-reactions-polls-system-hwea5i" />
|
|
32
40
|
</map>
|
|
33
41
|
</option>
|
|
34
42
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
@@ -44,12 +52,12 @@
|
|
|
44
52
|
<component name="GitRewordedCommitMessages">
|
|
45
53
|
<option name="commitMessagesMapping">
|
|
46
54
|
<RewordedCommitMessageMapping>
|
|
47
|
-
<option name="originalMessage" value="
|
|
48
|
-
<option name="rewordedMessage" value="
|
|
55
|
+
<option name="originalMessage" value="Role flags and the MentionAllRoles permission Re-exports the RoleFlag enum and registers the new permission bit, plus the types submodule bump carrying `Role.flags`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018QUxtDbWJMFih7bKH6thpn" />
|
|
56
|
+
<option name="rewordedMessage" value="Role flags and the MentionAllRoles permission" />
|
|
49
57
|
</RewordedCommitMessageMapping>
|
|
50
58
|
</option>
|
|
51
59
|
<option name="currentCommit" value="1" />
|
|
52
|
-
<option name="onto" value="
|
|
60
|
+
<option name="onto" value="54de756e28152bbda67a6480b48df607e3425e4a" />
|
|
53
61
|
</component>
|
|
54
62
|
<component name="GithubPullRequestsUISettings">{
|
|
55
63
|
"selectedUrlAndAccountId": {
|
|
@@ -253,23 +261,10 @@
|
|
|
253
261
|
<workItem from="1786526830597" duration="598000" />
|
|
254
262
|
<workItem from="1787125977456" duration="278000" />
|
|
255
263
|
<workItem from="1787576741803" duration="2076000" />
|
|
256
|
-
<workItem from="1787648458595" duration="
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
<
|
|
260
|
-
<created>1765145134871</created>
|
|
261
|
-
<option name="number" value="00067" />
|
|
262
|
-
<option name="presentableId" value="LOCAL-00067" />
|
|
263
|
-
<option name="project" value="LOCAL" />
|
|
264
|
-
<updated>1765145134871</updated>
|
|
265
|
-
</task>
|
|
266
|
-
<task id="LOCAL-00068" summary="Improve reconnect on timeout">
|
|
267
|
-
<option name="closed" value="true" />
|
|
268
|
-
<created>1765145773196</created>
|
|
269
|
-
<option name="number" value="00068" />
|
|
270
|
-
<option name="presentableId" value="LOCAL-00068" />
|
|
271
|
-
<option name="project" value="LOCAL" />
|
|
272
|
-
<updated>1765145773196</updated>
|
|
264
|
+
<workItem from="1787648458595" duration="3034000" />
|
|
265
|
+
<workItem from="1787994100244" duration="588000" />
|
|
266
|
+
<workItem from="1788873818076" duration="1523000" />
|
|
267
|
+
<workItem from="1788879390791" duration="2740000" />
|
|
273
268
|
</task>
|
|
274
269
|
<task id="LOCAL-00069" summary="Bump version">
|
|
275
270
|
<option name="closed" value="true" />
|
|
@@ -647,7 +642,23 @@
|
|
|
647
642
|
<option name="project" value="LOCAL" />
|
|
648
643
|
<updated>1787581107970</updated>
|
|
649
644
|
</task>
|
|
650
|
-
<
|
|
645
|
+
<task id="LOCAL-00116" summary="Bump version This reverts commit b9ff2004">
|
|
646
|
+
<option name="closed" value="true" />
|
|
647
|
+
<created>1787649696666</created>
|
|
648
|
+
<option name="number" value="00116" />
|
|
649
|
+
<option name="presentableId" value="LOCAL-00116" />
|
|
650
|
+
<option name="project" value="LOCAL" />
|
|
651
|
+
<updated>1787649696666</updated>
|
|
652
|
+
</task>
|
|
653
|
+
<task id="LOCAL-00117" summary="Bump version">
|
|
654
|
+
<option name="closed" value="true" />
|
|
655
|
+
<created>1788952429127</created>
|
|
656
|
+
<option name="number" value="00117" />
|
|
657
|
+
<option name="presentableId" value="LOCAL-00117" />
|
|
658
|
+
<option name="project" value="LOCAL" />
|
|
659
|
+
<updated>1788952429128</updated>
|
|
660
|
+
</task>
|
|
661
|
+
<option name="localTasksCounter" value="118" />
|
|
651
662
|
<servers />
|
|
652
663
|
</component>
|
|
653
664
|
<component name="TypeScriptGeneratedFilesManager">
|
|
@@ -664,6 +675,11 @@
|
|
|
664
675
|
<option value="master" />
|
|
665
676
|
</option>
|
|
666
677
|
</RecentGroup>
|
|
678
|
+
<RecentGroup>
|
|
679
|
+
<option name="FILTER_VALUES">
|
|
680
|
+
<option value="claude/role-flags-separation-mentions-g6v7s0" />
|
|
681
|
+
</option>
|
|
682
|
+
</RecentGroup>
|
|
667
683
|
<RecentGroup>
|
|
668
684
|
<option name="FILTER_VALUES">
|
|
669
685
|
<option value="claude/chat-reactions-polls-system-hwea5i" />
|
|
@@ -699,6 +715,11 @@
|
|
|
699
715
|
<entry key="MAIN">
|
|
700
716
|
<value>
|
|
701
717
|
<State>
|
|
718
|
+
<option name="CUSTOM_BOOLEAN_PROPERTIES">
|
|
719
|
+
<map>
|
|
720
|
+
<entry key="Show.Git.Branches" value="true" />
|
|
721
|
+
</map>
|
|
722
|
+
</option>
|
|
702
723
|
<option name="FILTERS">
|
|
703
724
|
<map>
|
|
704
725
|
<entry key="branch">
|
|
@@ -717,8 +738,6 @@
|
|
|
717
738
|
</option>
|
|
718
739
|
</component>
|
|
719
740
|
<component name="VcsManagerConfiguration">
|
|
720
|
-
<MESSAGE value="Fix room member update event handle" />
|
|
721
|
-
<MESSAGE value="Fix room member update event handle" />
|
|
722
741
|
<MESSAGE value="Add jumpTo message support" />
|
|
723
742
|
<MESSAGE value="Adjust to followed topics changes in protocol" />
|
|
724
743
|
<MESSAGE value="SetSessionData command support" />
|
|
@@ -731,7 +750,6 @@
|
|
|
731
750
|
<MESSAGE value="Fixes in WebApiChatClient" />
|
|
732
751
|
<MESSAGE value="Fix resolve window status after jump to message" />
|
|
733
752
|
<MESSAGE value="Fix jumpTo when window is in LIVE state" />
|
|
734
|
-
<MESSAGE value="Bump version" />
|
|
735
753
|
<MESSAGE value="Unread topic counter in summary, bump version" />
|
|
736
754
|
<MESSAGE value="Unread room counter in summary, bump version" />
|
|
737
755
|
<MESSAGE value="Reconcile tracked state on reconnect" />
|
|
@@ -742,7 +760,10 @@
|
|
|
742
760
|
<MESSAGE value="User presence status support" />
|
|
743
761
|
<MESSAGE value="Reacting changes" />
|
|
744
762
|
<MESSAGE value="Revert "User presence status support" This reverts commit b9ff2004" />
|
|
745
|
-
<
|
|
763
|
+
<MESSAGE value="Bump version This reverts commit b9ff2004" />
|
|
764
|
+
<MESSAGE value="Role flags and the MentionAllRoles permission" />
|
|
765
|
+
<MESSAGE value="Bump version" />
|
|
766
|
+
<option name="LAST_COMMIT_MESSAGE" value="Bump version" />
|
|
746
767
|
</component>
|
|
747
768
|
<component name="XSLT-Support.FileAssociations.UIState">
|
|
748
769
|
<expand />
|
package/README.md
CHANGED
|
@@ -24,6 +24,26 @@ TypeScript client library to handle connection with Devana (new Polfan) chat ser
|
|
|
24
24
|
})();
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
## Connection maintenance
|
|
28
|
+
|
|
29
|
+
`WebSocketChatClient` keeps the connection alive: after any loss (error, connecting timeout, missing pong, closure with
|
|
30
|
+
a code other than 1000) it reconnects indefinitely, with an exponential backoff between attempts. The `disconnect` event
|
|
31
|
+
tells whether a retry follows. A pending `connect()` promise resolves once an attempt authenticates, and is rejected by
|
|
32
|
+
`disconnect()`, which also stops reconnecting. An invalid token (`Bye` with `AuthenticationException`) rejects `connect()`
|
|
33
|
+
with the `Bye` data, emits an `error` event and stops reconnecting as well.
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const wsClient = new PServ.WebSocketChatClient({
|
|
37
|
+
token: 'your-access-token',
|
|
38
|
+
url: 'wss://pserv-websocket-address',
|
|
39
|
+
connectingTimeoutMs: 10000, // Per attempt (default)
|
|
40
|
+
reconnect: {
|
|
41
|
+
minDelayMs: 1000, // Delay before the first retry, doubled on every next one (default)
|
|
42
|
+
maxDelayMs: 30000, // Maximum delay between retries (default)
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
27
47
|
## State management
|
|
28
48
|
|
|
29
49
|
The library provides built-in state management for WebSocket client. To enable it, just pass `stateTracking`
|
package/build/index.cjs.js
CHANGED
|
@@ -48,6 +48,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
48
48
|
ObservableIndexedObjectCollection: () => (/* reexport */ ObservableIndexedObjectCollection),
|
|
49
49
|
PermissionDefinition: () => (/* reexport */ PermissionDefinition),
|
|
50
50
|
Permissions: () => (/* reexport */ Permissions),
|
|
51
|
+
RoleFlag: () => (/* reexport */ RoleFlag),
|
|
51
52
|
UserStatus: () => (/* reexport */ UserStatus),
|
|
52
53
|
WebApiChatClient: () => (/* reexport */ WebApiChatClient),
|
|
53
54
|
WebSocketChatClient: () => (/* reexport */ WebSocketChatClient),
|
|
@@ -4326,6 +4327,10 @@ Permissions_defineProperty(Permissions, "list", {
|
|
|
4326
4327
|
CreatePolls: {
|
|
4327
4328
|
value: 1 << 22,
|
|
4328
4329
|
maxLayer: Layer.Topic
|
|
4330
|
+
},
|
|
4331
|
+
MentionAllRoles: {
|
|
4332
|
+
value: 1 << 23,
|
|
4333
|
+
maxLayer: Layer.Topic
|
|
4329
4334
|
}
|
|
4330
4335
|
});
|
|
4331
4336
|
;// ./src/state-tracker/PermissionsManager.ts
|
|
@@ -5434,6 +5439,9 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5434
5439
|
WebSocketChatClient_defineProperty(_this, "pingMonitorInterval", void 0);
|
|
5435
5440
|
WebSocketChatClient_defineProperty(_this, "inFlightPingTimeout", void 0);
|
|
5436
5441
|
WebSocketChatClient_defineProperty(_this, "lastReceivedMessageAt", void 0);
|
|
5442
|
+
WebSocketChatClient_defineProperty(_this, "reconnectEnabled", false);
|
|
5443
|
+
WebSocketChatClient_defineProperty(_this, "reconnectTimeoutId", void 0);
|
|
5444
|
+
WebSocketChatClient_defineProperty(_this, "reconnectAttempts", 0);
|
|
5437
5445
|
_this.options = options;
|
|
5438
5446
|
if ((_this$options$stateTr = _this.options.stateTracking) !== null && _this$options$stateTr !== void 0 ? _this$options$stateTr : true) {
|
|
5439
5447
|
_this.state = new ChatStateTracker(_this);
|
|
@@ -5449,14 +5457,14 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5449
5457
|
key: "connect",
|
|
5450
5458
|
value: function () {
|
|
5451
5459
|
var _connect = WebSocketChatClient_asyncToGenerator(/*#__PURE__*/WebSocketChatClient_regenerator().m(function _callee() {
|
|
5452
|
-
var
|
|
5453
|
-
|
|
5454
|
-
_this$options$queryPa,
|
|
5455
|
-
_this$options$connect;
|
|
5456
|
-
var _this$connectPromise, params;
|
|
5460
|
+
var _this2 = this;
|
|
5461
|
+
var _this$connectPromise, connectPromise;
|
|
5457
5462
|
return WebSocketChatClient_regenerator().w(function (_context) {
|
|
5458
5463
|
while (1) switch (_context.n) {
|
|
5459
5464
|
case 0:
|
|
5465
|
+
this.reconnectEnabled = true;
|
|
5466
|
+
// A manual call does not wait for a scheduled retry.
|
|
5467
|
+
this.cancelScheduledReconnect();
|
|
5460
5468
|
if (!(this.isOpenWsState() || this.isConnectingWsState())) {
|
|
5461
5469
|
_context.n = 1;
|
|
5462
5470
|
break;
|
|
@@ -5466,26 +5474,23 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5466
5474
|
// Reuse the promise of an attempt that has not settled yet (an
|
|
5467
5475
|
// automatic reconnect), so the caller that started connecting is
|
|
5468
5476
|
// resolved by whichever attempt eventually authenticates.
|
|
5469
|
-
(
|
|
5470
|
-
|
|
5471
|
-
args
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
this.
|
|
5485
|
-
|
|
5486
|
-
}, (_this$options$connect = this.options.connectingTimeoutMs) !== null && _this$options$connect !== void 0 ? _this$options$connect : 10000);
|
|
5487
|
-
this.authenticated = false;
|
|
5488
|
-
return _context.a(2, this.connectPromise);
|
|
5477
|
+
if (!this.connectPromise) {
|
|
5478
|
+
this.connectPromise = new Promise(function () {
|
|
5479
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
5480
|
+
args[_key] = arguments[_key];
|
|
5481
|
+
}
|
|
5482
|
+
return _this2.authenticatedResolvers = args;
|
|
5483
|
+
});
|
|
5484
|
+
// Automatic reconnects create this promise with no one awaiting it,
|
|
5485
|
+
// so its rejection must not surface as an unhandled one. Callers
|
|
5486
|
+
// awaiting it still receive the rejection.
|
|
5487
|
+
this.connectPromise["catch"](function () {
|
|
5488
|
+
return undefined;
|
|
5489
|
+
});
|
|
5490
|
+
}
|
|
5491
|
+
connectPromise = this.connectPromise;
|
|
5492
|
+
this.openSocket();
|
|
5493
|
+
return _context.a(2, connectPromise);
|
|
5489
5494
|
}
|
|
5490
5495
|
}, _callee, this);
|
|
5491
5496
|
}));
|
|
@@ -5497,10 +5502,16 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5497
5502
|
}, {
|
|
5498
5503
|
key: "disconnect",
|
|
5499
5504
|
value: function disconnect() {
|
|
5500
|
-
var
|
|
5505
|
+
var wasActive = this.ws !== null || this.reconnectTimeoutId !== undefined;
|
|
5506
|
+
this.reconnectEnabled = false;
|
|
5507
|
+
this.reconnectAttempts = 0;
|
|
5508
|
+
this.cancelScheduledReconnect();
|
|
5509
|
+
this.releaseSocket(1000); // Normal closure
|
|
5501
5510
|
this.failPendingCommands(new Error('Client disconnected before the command was answered'));
|
|
5502
|
-
|
|
5503
|
-
|
|
5511
|
+
this.settleConnect(new Error('Client disconnected before authentication'));
|
|
5512
|
+
if (wasActive) {
|
|
5513
|
+
this.emit(this.Event.disconnect, false);
|
|
5514
|
+
}
|
|
5504
5515
|
}
|
|
5505
5516
|
}, {
|
|
5506
5517
|
key: "send",
|
|
@@ -5534,15 +5545,52 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5534
5545
|
get: function get() {
|
|
5535
5546
|
return this.isOpenWsState() && this.authenticated;
|
|
5536
5547
|
}
|
|
5548
|
+
}, {
|
|
5549
|
+
key: "openSocket",
|
|
5550
|
+
value: function openSocket() {
|
|
5551
|
+
var _this$options$queryPa,
|
|
5552
|
+
_this3 = this,
|
|
5553
|
+
_this$options$connect;
|
|
5554
|
+
// Never leave a previous socket attached (e.g. one still closing).
|
|
5555
|
+
this.releaseSocket(1000);
|
|
5556
|
+
var params = new URLSearchParams((_this$options$queryPa = this.options.queryParams) !== null && _this$options$queryPa !== void 0 ? _this$options$queryPa : {});
|
|
5557
|
+
params.set('token', this.options.token);
|
|
5558
|
+
var ws;
|
|
5559
|
+
try {
|
|
5560
|
+
ws = new WebSocket("".concat(this.options.url, "?").concat(params));
|
|
5561
|
+
} catch (error) {
|
|
5562
|
+
// Invalid URL - no retry can fix that.
|
|
5563
|
+
this.settleConnect(error);
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
// Events of an abandoned socket must not touch the current connection.
|
|
5568
|
+
ws.onmessage = function (ev) {
|
|
5569
|
+
return ws === _this3.ws && _this3.onMessage(ev);
|
|
5570
|
+
};
|
|
5571
|
+
ws.onclose = function (ev) {
|
|
5572
|
+
return ws === _this3.ws && _this3.onClose(ev);
|
|
5573
|
+
};
|
|
5574
|
+
// Not every implementation follows a failed handshake with a close
|
|
5575
|
+
// event (e.g. Node.js), so an error alone means the connection is lost.
|
|
5576
|
+
ws.onerror = function () {
|
|
5577
|
+
return ws === _this3.ws && _this3.handleConnectionLoss(true);
|
|
5578
|
+
};
|
|
5579
|
+
this.ws = ws;
|
|
5580
|
+
this.authenticated = false;
|
|
5581
|
+
this.connectingTimeoutId = setTimeout(function () {
|
|
5582
|
+
return _this3.triggerConnectionTimeout();
|
|
5583
|
+
}, (_this$options$connect = this.options.connectingTimeoutMs) !== null && _this$options$connect !== void 0 ? _this$options$connect : 10000);
|
|
5584
|
+
}
|
|
5537
5585
|
}, {
|
|
5538
5586
|
key: "sendEnvelope",
|
|
5539
5587
|
value: function sendEnvelope(envelope) {
|
|
5540
|
-
var _this$ws$readyState, _this$
|
|
5588
|
+
var _this$ws$readyState, _this$ws;
|
|
5541
5589
|
if (this.isReady) {
|
|
5542
5590
|
this.ws.send(JSON.stringify(envelope));
|
|
5543
5591
|
return;
|
|
5544
5592
|
}
|
|
5545
|
-
this.handleEnvelopeSendError(envelope, new Error("Cannot send - client is not ready (state=".concat((_this$ws$readyState = (_this$
|
|
5593
|
+
this.handleEnvelopeSendError(envelope, new Error("Cannot send - client is not ready (state=".concat((_this$ws$readyState = (_this$ws = this.ws) === null || _this$ws === void 0 ? void 0 : _this$ws.readyState) !== null && _this$ws$readyState !== void 0 ? _this$ws$readyState : '[no connection]', "; authenticated=").concat(this.authenticated, ")")));
|
|
5546
5594
|
}
|
|
5547
5595
|
}, {
|
|
5548
5596
|
key: "onMessage",
|
|
@@ -5558,35 +5606,110 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5558
5606
|
var isAuthenticated = envelope.type !== 'Bye';
|
|
5559
5607
|
this.authenticated = isAuthenticated;
|
|
5560
5608
|
if (isAuthenticated) {
|
|
5609
|
+
this.reconnectAttempts = 0;
|
|
5561
5610
|
this.startConnectionMonitor();
|
|
5562
5611
|
this.settleConnect();
|
|
5563
5612
|
this.emit(this.Event.connect);
|
|
5564
5613
|
this.sendFromQueue();
|
|
5565
5614
|
} else {
|
|
5615
|
+
var _envelope$data;
|
|
5566
5616
|
this.settleConnect(envelope.data);
|
|
5617
|
+
var error = (_envelope$data = envelope.data) === null || _envelope$data === void 0 || (_envelope$data = _envelope$data.reason) === null || _envelope$data === void 0 ? void 0 : _envelope$data.error;
|
|
5618
|
+
if ((error === null || error === void 0 ? void 0 : error.code) === 'AuthenticationException') {
|
|
5619
|
+
// Invalid token - retrying would be rejected the same way.
|
|
5620
|
+
this.handleConnectionLoss(false);
|
|
5621
|
+
this.emit(this.Event.error, new Error("Authentication rejected: ".concat(error.message)));
|
|
5622
|
+
}
|
|
5567
5623
|
}
|
|
5568
5624
|
}
|
|
5569
5625
|
}
|
|
5570
5626
|
}, {
|
|
5571
5627
|
key: "onClose",
|
|
5572
5628
|
value: function onClose(event) {
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5629
|
+
// Connection was closed because of error
|
|
5630
|
+
this.handleConnectionLoss(event.code !== 1000);
|
|
5631
|
+
}
|
|
5632
|
+
|
|
5633
|
+
/**
|
|
5634
|
+
* Abandon the current socket without waiting for its close event (which
|
|
5635
|
+
* may never come, or take minutes on a dead TCP connection), settle
|
|
5636
|
+
* everything that depended on it and schedule a retry when requested.
|
|
5637
|
+
*/
|
|
5638
|
+
}, {
|
|
5639
|
+
key: "handleConnectionLoss",
|
|
5640
|
+
value: function handleConnectionLoss(reconnect) {
|
|
5641
|
+
this.releaseSocket(reconnect ? 3000 : 1000);
|
|
5576
5642
|
|
|
5577
5643
|
// The server can no longer answer anything that was queued or in
|
|
5578
5644
|
// flight, so settle those promises instead of leaving them pending.
|
|
5579
5645
|
this.failPendingCommands(new Error('Connection closed before the command was answered'));
|
|
5646
|
+
reconnect && (reconnect = this.reconnectEnabled);
|
|
5580
5647
|
if (reconnect) {
|
|
5581
5648
|
// Keep a pending connect() promise unsettled - the retry below is
|
|
5582
5649
|
// expected to authenticate and will resolve it.
|
|
5583
|
-
|
|
5650
|
+
this.scheduleReconnect();
|
|
5584
5651
|
} else {
|
|
5652
|
+
this.reconnectEnabled = false;
|
|
5585
5653
|
this.settleConnect(new Error('Connection closed before authentication'));
|
|
5586
5654
|
}
|
|
5587
5655
|
this.emit(this.Event.disconnect, reconnect);
|
|
5588
5656
|
}
|
|
5589
5657
|
|
|
5658
|
+
/**
|
|
5659
|
+
* Detach the current socket from the client and close it if it is still
|
|
5660
|
+
* alive, together with all timers bound to it.
|
|
5661
|
+
*/
|
|
5662
|
+
}, {
|
|
5663
|
+
key: "releaseSocket",
|
|
5664
|
+
value: function releaseSocket(closeCode) {
|
|
5665
|
+
this.stopConnectionMonitor();
|
|
5666
|
+
clearTimeout(this.connectingTimeoutId);
|
|
5667
|
+
this.connectingTimeoutId = undefined;
|
|
5668
|
+
this.authenticated = false;
|
|
5669
|
+
var ws = this.ws;
|
|
5670
|
+
this.ws = null;
|
|
5671
|
+
if (!ws) {
|
|
5672
|
+
return;
|
|
5673
|
+
}
|
|
5674
|
+
ws.onmessage = ws.onclose = ws.onerror = null;
|
|
5675
|
+
if (ws.readyState === ws.CONNECTING || ws.readyState === ws.OPEN) {
|
|
5676
|
+
try {
|
|
5677
|
+
ws.close(closeCode);
|
|
5678
|
+
} catch (_unused) {
|
|
5679
|
+
// Nothing more can be done with a broken socket.
|
|
5680
|
+
}
|
|
5681
|
+
}
|
|
5682
|
+
}
|
|
5683
|
+
}, {
|
|
5684
|
+
key: "scheduleReconnect",
|
|
5685
|
+
value: function scheduleReconnect() {
|
|
5686
|
+
var _this$options$reconne,
|
|
5687
|
+
_this$options$reconne2,
|
|
5688
|
+
_this$options$reconne3,
|
|
5689
|
+
_this$options$reconne4,
|
|
5690
|
+
_this4 = this;
|
|
5691
|
+
this.cancelScheduledReconnect();
|
|
5692
|
+
var minDelay = Math.max(0, (_this$options$reconne = (_this$options$reconne2 = this.options.reconnect) === null || _this$options$reconne2 === void 0 ? void 0 : _this$options$reconne2.minDelayMs) !== null && _this$options$reconne !== void 0 ? _this$options$reconne : 1000);
|
|
5693
|
+
var maxDelay = Math.max(minDelay, (_this$options$reconne3 = (_this$options$reconne4 = this.options.reconnect) === null || _this$options$reconne4 === void 0 ? void 0 : _this$options$reconne4.maxDelayMs) !== null && _this$options$reconne3 !== void 0 ? _this$options$reconne3 : 30000);
|
|
5694
|
+
var delay = Math.min(maxDelay, minDelay * Math.pow(2, Math.min(this.reconnectAttempts, 30)));
|
|
5695
|
+
this.reconnectAttempts++;
|
|
5696
|
+
|
|
5697
|
+
// Random jitter (50-100% of the delay) keeps clients from reconnecting
|
|
5698
|
+
// in lockstep after a server restart.
|
|
5699
|
+
this.reconnectTimeoutId = setTimeout(function () {
|
|
5700
|
+
_this4.reconnectTimeoutId = undefined;
|
|
5701
|
+
_this4.connect()["catch"](function () {
|
|
5702
|
+
return undefined;
|
|
5703
|
+
});
|
|
5704
|
+
}, delay / 2 + Math.random() * delay / 2);
|
|
5705
|
+
}
|
|
5706
|
+
}, {
|
|
5707
|
+
key: "cancelScheduledReconnect",
|
|
5708
|
+
value: function cancelScheduledReconnect() {
|
|
5709
|
+
clearTimeout(this.reconnectTimeoutId);
|
|
5710
|
+
this.reconnectTimeoutId = undefined;
|
|
5711
|
+
}
|
|
5712
|
+
|
|
5590
5713
|
/**
|
|
5591
5714
|
* Resolve (or reject, when an error is given) a pending connect() promise.
|
|
5592
5715
|
* No-op when there is nothing pending.
|
|
@@ -5629,16 +5752,16 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5629
5752
|
}, {
|
|
5630
5753
|
key: "sendFromQueue",
|
|
5631
5754
|
value: function sendFromQueue() {
|
|
5632
|
-
var
|
|
5755
|
+
var _this5 = this;
|
|
5633
5756
|
// Send awaiting data to server
|
|
5634
5757
|
var lastDelay = 0;
|
|
5635
5758
|
var _loop = function _loop() {
|
|
5636
|
-
var
|
|
5637
|
-
var envelope =
|
|
5759
|
+
var _this5$options$awaitQ;
|
|
5760
|
+
var envelope = _this5.sendQueue[dataIndex];
|
|
5638
5761
|
setTimeout(function () {
|
|
5639
|
-
return
|
|
5762
|
+
return _this5.sendEnvelope(envelope);
|
|
5640
5763
|
}, lastDelay);
|
|
5641
|
-
lastDelay += (
|
|
5764
|
+
lastDelay += (_this5$options$awaitQ = _this5.options.awaitQueueSendDelayMs) !== null && _this5$options$awaitQ !== void 0 ? _this5$options$awaitQ : 500;
|
|
5642
5765
|
};
|
|
5643
5766
|
for (var dataIndex in this.sendQueue) {
|
|
5644
5767
|
_loop();
|
|
@@ -5649,7 +5772,7 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5649
5772
|
}, {
|
|
5650
5773
|
key: "triggerConnectionTimeout",
|
|
5651
5774
|
value: function triggerConnectionTimeout() {
|
|
5652
|
-
this.
|
|
5775
|
+
this.handleConnectionLoss(true);
|
|
5653
5776
|
this.emit(this.Event.error, new Error('Connection timeout'));
|
|
5654
5777
|
}
|
|
5655
5778
|
}, {
|
|
@@ -5665,7 +5788,8 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5665
5788
|
}, {
|
|
5666
5789
|
key: "startConnectionMonitor",
|
|
5667
5790
|
value: function startConnectionMonitor() {
|
|
5668
|
-
var
|
|
5791
|
+
var _this6 = this;
|
|
5792
|
+
this.stopConnectionMonitor();
|
|
5669
5793
|
if (!this.options.ping.enabled) {
|
|
5670
5794
|
return;
|
|
5671
5795
|
}
|
|
@@ -5674,30 +5798,32 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
|
|
|
5674
5798
|
return WebSocketChatClient_regenerator().w(function (_context3) {
|
|
5675
5799
|
while (1) switch (_context3.n) {
|
|
5676
5800
|
case 0:
|
|
5677
|
-
if (!(!
|
|
5801
|
+
if (!(!_this6.isReady || _this6.inFlightPingTimeout)) {
|
|
5678
5802
|
_context3.n = 1;
|
|
5679
5803
|
break;
|
|
5680
5804
|
}
|
|
5681
5805
|
return _context3.a(2);
|
|
5682
5806
|
case 1:
|
|
5683
|
-
if (!(Date.now() -
|
|
5807
|
+
if (!(Date.now() - _this6.lastReceivedMessageAt < _this6.options.ping.noActivityTimeoutMs)) {
|
|
5684
5808
|
_context3.n = 2;
|
|
5685
5809
|
break;
|
|
5686
5810
|
}
|
|
5687
5811
|
return _context3.a(2);
|
|
5688
5812
|
case 2:
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5813
|
+
_this6.inFlightPingTimeout = setTimeout(function () {
|
|
5814
|
+
_this6.inFlightPingTimeout = undefined;
|
|
5815
|
+
// Closing a dead connection can hang in CLOSING for minutes,
|
|
5816
|
+
// so drop it right away instead of waiting for the close event.
|
|
5817
|
+
_this6.handleConnectionLoss(true);
|
|
5818
|
+
}, _this6.options.ping.pongBackTimeoutMs);
|
|
5693
5819
|
|
|
5694
5820
|
// A rejection here means the connection dropped while the ping was
|
|
5695
|
-
// in flight;
|
|
5696
|
-
|
|
5821
|
+
// in flight; the loss is already handled, so just stop waiting.
|
|
5822
|
+
_this6.send('Ping', {})["catch"](function () {
|
|
5697
5823
|
return undefined;
|
|
5698
5824
|
}).then(function () {
|
|
5699
|
-
clearTimeout(
|
|
5700
|
-
|
|
5825
|
+
clearTimeout(_this6.inFlightPingTimeout);
|
|
5826
|
+
_this6.inFlightPingTimeout = undefined;
|
|
5701
5827
|
});
|
|
5702
5828
|
case 3:
|
|
5703
5829
|
return _context3.a(2);
|
|
@@ -6134,6 +6260,21 @@ var FilesClient = /*#__PURE__*/function (_AbstractRestClient) {
|
|
|
6134
6260
|
}()
|
|
6135
6261
|
}]);
|
|
6136
6262
|
}(AbstractRestClient);
|
|
6263
|
+
;// ./src/types/src/schemes/Role.ts
|
|
6264
|
+
/**
|
|
6265
|
+
* Bit flags of a role, stored in {@link Role.flags}.
|
|
6266
|
+
*
|
|
6267
|
+
* - `SeparateOnMembersList` - available holders of the role are listed in their
|
|
6268
|
+
* own group of the members list, headed by the role name.
|
|
6269
|
+
* - `MentionableByEveryone` - anybody may mention the role with notification
|
|
6270
|
+
* effects; without it the mention is decorative only, unless the author holds
|
|
6271
|
+
* the `MentionAllRoles` permission.
|
|
6272
|
+
*/
|
|
6273
|
+
var RoleFlag = /*#__PURE__*/function (RoleFlag) {
|
|
6274
|
+
RoleFlag[RoleFlag["SeparateOnMembersList"] = 1] = "SeparateOnMembersList";
|
|
6275
|
+
RoleFlag[RoleFlag["MentionableByEveryone"] = 2] = "MentionableByEveryone";
|
|
6276
|
+
return RoleFlag;
|
|
6277
|
+
}({});
|
|
6137
6278
|
;// ./src/types/src/schemes/User.ts
|
|
6138
6279
|
/**
|
|
6139
6280
|
* Availability of a user, aggregated over all of their sessions.
|