polfan-server-js-client 0.2.65 → 0.2.67

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.
@@ -4,14 +4,13 @@
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="Align to custom colors and nicks protocol changes">
8
- <change beforePath="$PROJECT_DIR$/build/index.cjs.js" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.cjs.js" afterDir="false" />
9
- <change beforePath="$PROJECT_DIR$/build/index.cjs.js.map" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.cjs.js.map" afterDir="false" />
10
- <change beforePath="$PROJECT_DIR$/build/index.umd.js" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.umd.js" afterDir="false" />
11
- <change beforePath="$PROJECT_DIR$/build/index.umd.js.map" beforeDir="false" afterPath="$PROJECT_DIR$/build/index.umd.js.map" afterDir="false" />
12
- <change beforePath="$PROJECT_DIR$/build/types/WebSocketChatClient.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/build/types/WebSocketChatClient.d.ts" afterDir="false" />
13
- <change beforePath="$PROJECT_DIR$/package.json" beforeDir="false" afterPath="$PROJECT_DIR$/package.json" afterDir="false" />
7
+ <list default="true" id="831dae43-0da1-47fd-a5f7-33dd5eec2992" name="Changes" comment="Connection handling optimizations">
8
+ <change afterPath="$PROJECT_DIR$/src/types/src/schemes/commands/Ping.ts" afterDir="false" />
9
+ <change afterPath="$PROJECT_DIR$/src/types/src/schemes/events/Pong.ts" afterDir="false" />
10
+ <change beforePath="$PROJECT_DIR$/src/AbstractChatClient.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/AbstractChatClient.ts" afterDir="false" />
14
11
  <change beforePath="$PROJECT_DIR$/src/WebSocketChatClient.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/WebSocketChatClient.ts" afterDir="false" />
12
+ <change beforePath="$PROJECT_DIR$/src/types" beforeDir="false" afterPath="$PROJECT_DIR$/src/types" afterDir="false" />
13
+ <change beforePath="$PROJECT_DIR$/src/types/src/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/types/src/index.ts" afterDir="false" />
15
14
  </list>
16
15
  <option name="SHOW_DIALOG" value="false" />
17
16
  <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -163,15 +162,7 @@
163
162
  <workItem from="1764758258935" duration="1127000" />
164
163
  <workItem from="1764792690210" duration="1002000" />
165
164
  <workItem from="1764794428269" duration="595000" />
166
- <workItem from="1764847260499" duration="4990000" />
167
- </task>
168
- <task id="LOCAL-00017" summary="New scheme of Bye event">
169
- <option name="closed" value="true" />
170
- <created>1740250355576</created>
171
- <option name="number" value="00017" />
172
- <option name="presentableId" value="LOCAL-00017" />
173
- <option name="project" value="LOCAL" />
174
- <updated>1740250355576</updated>
165
+ <workItem from="1764847260499" duration="25756000" />
175
166
  </task>
176
167
  <task id="LOCAL-00018" summary="Fix authentication">
177
168
  <option name="closed" value="true" />
@@ -557,7 +548,15 @@
557
548
  <option name="project" value="LOCAL" />
558
549
  <updated>1764689897014</updated>
559
550
  </task>
560
- <option name="localTasksCounter" value="66" />
551
+ <task id="LOCAL-00066" summary="Connection handling optimizations">
552
+ <option name="closed" value="true" />
553
+ <created>1764955397384</created>
554
+ <option name="number" value="00066" />
555
+ <option name="presentableId" value="LOCAL-00066" />
556
+ <option name="project" value="LOCAL" />
557
+ <updated>1764955397384</updated>
558
+ </task>
559
+ <option name="localTasksCounter" value="67" />
561
560
  <servers />
562
561
  </component>
563
562
  <component name="TypeScriptGeneratedFilesManager">
@@ -575,7 +574,6 @@
575
574
  </option>
576
575
  </component>
577
576
  <component name="VcsManagerConfiguration">
578
- <MESSAGE value="Fix package.json exports" />
579
577
  <MESSAGE value="Fix package.json type exports" />
580
578
  <MESSAGE value="New message type" />
581
579
  <MESSAGE value="Dedicated event for user status change" />
@@ -600,7 +598,8 @@
600
598
  <MESSAGE value="Update deps and improve library building" />
601
599
  <MESSAGE value="Improvements and fixes to collection mirroring" />
602
600
  <MESSAGE value="Align to custom colors and nicks protocol changes" />
603
- <option name="LAST_COMMIT_MESSAGE" value="Align to custom colors and nicks protocol changes" />
601
+ <MESSAGE value="Connection handling optimizations" />
602
+ <option name="LAST_COMMIT_MESSAGE" value="Connection handling optimizations" />
604
603
  </component>
605
604
  <component name="github-copilot-workspace">
606
605
  <instructionFileLocations>
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # pserv-js-client-library
2
- TypeScript client library to handle connection with Polfan chat service.
2
+ TypeScript client library to handle connection with Devana (new Polfan) chat service.
3
3
 
4
4
  ## How to use?
5
5
 
@@ -22,4 +22,24 @@ TypeScript client library to handle connection with Polfan chat service.
22
22
  console.log("The spaces you are in:", session.spaces);
23
23
  console.log("The version of server you connected to:", session.serverVersion);
24
24
  })();
25
- ```
25
+ ```
26
+
27
+ ## State management
28
+
29
+ The library provides built-in state management for WebSocket client. To enable it, just pass `stateTracking`
30
+ option to the `WebSocketChatClient` constructor:
31
+
32
+ ```js
33
+ const wsClient = new PServ.WebSocketChatClient({
34
+ token: 'your-access-token',
35
+ url: 'wss://pserv-websocket-address',
36
+ stateTracking: true, // Enable state tracking
37
+ });
38
+ ```
39
+
40
+ With state tracking enabled, the client will automatically maintain the current state of rooms, users, and messages,
41
+ by handling incoming events from the server. Reactive data structures are available via `ObservableIndexedObjectCollection`
42
+ objects, which allows you to subscribe to changes.
43
+
44
+ **Important note:** you can cache these objects for the connection lifetime, but you should refetch them after reconnecting,
45
+ because some structures are rebuild from scratch on `Session` event.
@@ -968,9 +968,6 @@ var TopicHistoryWindow = /*#__PURE__*/function (_TraversableRemoteCol) {
968
968
  _this2.tracker = tracker;
969
969
  _this2.internalState.traverseLock = false;
970
970
  if (bindEvents) {
971
- _this2.tracker.client.on('Session', function (ev) {
972
- return _this2.handleSession(ev);
973
- });
974
971
  _this2.tracker.client.on('NewMessage', function (ev) {
975
972
  return _this2.handleNewMessage(ev);
976
973
  });
@@ -1117,19 +1114,6 @@ var TopicHistoryWindow = /*#__PURE__*/function (_TraversableRemoteCol) {
1117
1114
  }
1118
1115
  return handleNewMessage;
1119
1116
  }()
1120
- }, {
1121
- key: "handleSession",
1122
- value: function handleSession(ev) {
1123
- var _this3 = this;
1124
- var rooms = ev.state.rooms;
1125
- if (rooms.find(function (room) {
1126
- return room.id === _this3.roomId;
1127
- })) {
1128
- void this.resetToLatest();
1129
- } else {
1130
- this.deleteAll();
1131
- }
1132
- }
1133
1117
  }, {
1134
1118
  key: "fetchItemsAfter",
1135
1119
  value: function () {
@@ -4285,7 +4269,7 @@ var WebSocketChatClientEvent = /*#__PURE__*/function (WebSocketChatClientEvent)
4285
4269
  }(WebSocketChatClientEvent || {});
4286
4270
  var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4287
4271
  function WebSocketChatClient(options) {
4288
- var _this$options$stateTr;
4272
+ var _this$options$stateTr, _options$ping, _options$ping2, _options$ping2$enable, _options$ping3, _options$ping3$noActi, _options$ping4, _options$ping4$pongBa;
4289
4273
  var _this;
4290
4274
  WebSocketChatClient_classCallCheck(this, WebSocketChatClient);
4291
4275
  _this = WebSocketChatClient_callSuper(this, WebSocketChatClient);
@@ -4296,10 +4280,17 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4296
4280
  WebSocketChatClient_defineProperty(_this, "connectingTimeoutId", void 0);
4297
4281
  WebSocketChatClient_defineProperty(_this, "authenticated", void 0);
4298
4282
  WebSocketChatClient_defineProperty(_this, "authenticatedResolvers", void 0);
4283
+ WebSocketChatClient_defineProperty(_this, "pingIntervalId", void 0);
4284
+ WebSocketChatClient_defineProperty(_this, "lastReceivedMessageAt", void 0);
4285
+ WebSocketChatClient_defineProperty(_this, "pingInFlight", void 0);
4299
4286
  _this.options = options;
4300
4287
  if ((_this$options$stateTr = _this.options.stateTracking) !== null && _this$options$stateTr !== void 0 ? _this$options$stateTr : true) {
4301
4288
  _this.state = new ChatStateTracker(_this);
4302
4289
  }
4290
+ (_options$ping = options.ping) !== null && _options$ping !== void 0 ? _options$ping : options.ping = {};
4291
+ (_options$ping2$enable = (_options$ping2 = options.ping).enabled) !== null && _options$ping2$enable !== void 0 ? _options$ping2$enable : _options$ping2.enabled = true;
4292
+ (_options$ping3$noActi = (_options$ping3 = options.ping).noActivityTimeoutMs) !== null && _options$ping3$noActi !== void 0 ? _options$ping3$noActi : _options$ping3.noActivityTimeoutMs = 15000;
4293
+ (_options$ping4$pongBa = (_options$ping4 = options.ping).pongBackTimeoutMs) !== null && _options$ping4$pongBa !== void 0 ? _options$ping4$pongBa : _options$ping4.pongBackTimeoutMs = 5000;
4303
4294
  return _this;
4304
4295
  }
4305
4296
  WebSocketChatClient_inherits(WebSocketChatClient, _AbstractChatClient);
@@ -4352,7 +4343,7 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4352
4343
  value: function disconnect() {
4353
4344
  var _this$ws;
4354
4345
  this.sendQueue = [];
4355
- (_this$ws = this.ws) === null || _this$ws === void 0 || _this$ws.close();
4346
+ (_this$ws = this.ws) === null || _this$ws === void 0 || _this$ws.close(1000); // Normal closure
4356
4347
  this.ws = null;
4357
4348
  }
4358
4349
  }, {
@@ -4400,6 +4391,7 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4400
4391
  }, {
4401
4392
  key: "onMessage",
4402
4393
  value: function onMessage(event) {
4394
+ this.lastReceivedMessageAt = Date.now();
4403
4395
  var envelope = JSON.parse(event.data);
4404
4396
  this.handleIncomingEnvelope(envelope);
4405
4397
  this.emit(envelope.type, envelope.data);
@@ -4410,6 +4402,7 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4410
4402
  var isAuthenticated = envelope.type !== 'Bye';
4411
4403
  this.authenticated = isAuthenticated;
4412
4404
  if (isAuthenticated) {
4405
+ this.startConnectionMonitor();
4413
4406
  this.authenticatedResolvers[0]();
4414
4407
  this.emit(this.Event.connect);
4415
4408
  this.sendFromQueue();
@@ -4421,6 +4414,7 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4421
4414
  }, {
4422
4415
  key: "onClose",
4423
4416
  value: function onClose(event) {
4417
+ this.stopConnectionMonitor();
4424
4418
  clearTimeout(this.connectingTimeoutId);
4425
4419
  var reconnect = event.code !== 1000; // Connection was closed because of error
4426
4420
  if (reconnect) {
@@ -4464,6 +4458,56 @@ var WebSocketChatClient = /*#__PURE__*/function (_AbstractChatClient) {
4464
4458
  value: function isOpenWsState() {
4465
4459
  return this.ws && this.ws.readyState === this.ws.OPEN;
4466
4460
  }
4461
+ }, {
4462
+ key: "startConnectionMonitor",
4463
+ value: function startConnectionMonitor() {
4464
+ var _this4 = this;
4465
+ if (!this.options.ping.enabled) {
4466
+ return;
4467
+ }
4468
+ this.lastReceivedMessageAt = Date.now();
4469
+ this.pingIntervalId = setInterval(/*#__PURE__*/WebSocketChatClient_asyncToGenerator(/*#__PURE__*/WebSocketChatClient_regenerator().m(function _callee3() {
4470
+ var timeout;
4471
+ return WebSocketChatClient_regenerator().w(function (_context3) {
4472
+ while (1) switch (_context3.n) {
4473
+ case 0:
4474
+ if (!(!_this4.isReady || _this4.pingInFlight)) {
4475
+ _context3.n = 1;
4476
+ break;
4477
+ }
4478
+ return _context3.a(2);
4479
+ case 1:
4480
+ if (!(Date.now() - _this4.lastReceivedMessageAt < _this4.options.ping.noActivityTimeoutMs)) {
4481
+ _context3.n = 2;
4482
+ break;
4483
+ }
4484
+ return _context3.a(2);
4485
+ case 2:
4486
+ timeout = setTimeout(function () {
4487
+ _this4.pingInFlight = false;
4488
+ _this4.disconnect();
4489
+ void _this4.connect();
4490
+ }, _this4.options.ping.pongBackTimeoutMs);
4491
+ _this4.pingInFlight = true;
4492
+ _this4.send('Ping', {}).then(function () {
4493
+ _this4.pingInFlight = false;
4494
+ clearTimeout(timeout);
4495
+ });
4496
+ case 3:
4497
+ return _context3.a(2);
4498
+ }
4499
+ }, _callee3);
4500
+ })), 1000);
4501
+ }
4502
+ }, {
4503
+ key: "stopConnectionMonitor",
4504
+ value: function stopConnectionMonitor() {
4505
+ if (this.pingIntervalId) {
4506
+ clearInterval(this.pingIntervalId);
4507
+ this.pingIntervalId = undefined;
4508
+ }
4509
+ this.pingInFlight = false;
4510
+ }
4467
4511
  }]);
4468
4512
  }(AbstractChatClient);
4469
4513
  ;// ./src/WebApiChatClient.ts