@pluv/client 0.43.0 → 0.44.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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +13 -0
- package/dist/index.d.mts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +36 -29
- package/dist/index.mjs +36 -29
- package/package.json +5 -5
- package/src/CrdtManager.ts +1 -1
- package/src/PluvRoom.ts +20 -6
- package/src/enums.ts +9 -7
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/client@0.
|
|
2
|
+
> @pluv/client@0.44.0 build /home/runner/work/pluv/pluv/packages/client
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[
|
|
12
|
-
[
|
|
13
|
-
[
|
|
14
|
-
[
|
|
11
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m56.45 KB[39m
|
|
12
|
+
[32mESM[39m ⚡️ Build success in 112ms
|
|
13
|
+
[32mCJS[39m [1mdist/index.js [22m[32m57.76 KB[39m
|
|
14
|
+
[32mCJS[39m ⚡️ Build success in 112ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[32m25.
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[32m25.
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 3446ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m25.36 KB[39m
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m25.36 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @pluv/client
|
|
2
2
|
|
|
3
|
+
## 0.44.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c9fcea5: **BREAKING** The `ConnectionState` enum is now a `const` to avoid several pitfalls of using TypeScript enums.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- fba9354: Fix potential edge case where event handlers may be called redundantly.
|
|
12
|
+
- bc2d684: Fix `PluvRoom` not properly reconnecting when connections are unavailable.
|
|
13
|
+
- @pluv/crdt@0.44.0
|
|
14
|
+
- @pluv/types@0.44.0
|
|
15
|
+
|
|
3
16
|
## 0.43.0
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -6,13 +6,14 @@ import { Subject } from 'wonka';
|
|
|
6
6
|
|
|
7
7
|
type EventNotifierSubscriptionCallback<TIO extends IOLike<any, any>, TEvent extends keyof InferIOOutput<TIO>> = (value: Id<IOEventMessage<TIO, TEvent>>) => void;
|
|
8
8
|
|
|
9
|
-
declare
|
|
10
|
-
Closed
|
|
11
|
-
Connecting
|
|
12
|
-
Open
|
|
13
|
-
Unavailable
|
|
14
|
-
Untouched
|
|
15
|
-
}
|
|
9
|
+
declare const ConnectionState: {
|
|
10
|
+
readonly Closed: "Closed";
|
|
11
|
+
readonly Connecting: "Connecting";
|
|
12
|
+
readonly Open: "Open";
|
|
13
|
+
readonly Unavailable: "Unavailable";
|
|
14
|
+
readonly Untouched: "Untouched";
|
|
15
|
+
};
|
|
16
|
+
type ConnectionState = (typeof ConnectionState)[keyof typeof ConnectionState];
|
|
16
17
|
|
|
17
18
|
declare const identity: <T extends unknown>(x: T) => T;
|
|
18
19
|
|
package/dist/index.d.ts
CHANGED
|
@@ -6,13 +6,14 @@ import { Subject } from 'wonka';
|
|
|
6
6
|
|
|
7
7
|
type EventNotifierSubscriptionCallback<TIO extends IOLike<any, any>, TEvent extends keyof InferIOOutput<TIO>> = (value: Id<IOEventMessage<TIO, TEvent>>) => void;
|
|
8
8
|
|
|
9
|
-
declare
|
|
10
|
-
Closed
|
|
11
|
-
Connecting
|
|
12
|
-
Open
|
|
13
|
-
Unavailable
|
|
14
|
-
Untouched
|
|
15
|
-
}
|
|
9
|
+
declare const ConnectionState: {
|
|
10
|
+
readonly Closed: "Closed";
|
|
11
|
+
readonly Connecting: "Connecting";
|
|
12
|
+
readonly Open: "Open";
|
|
13
|
+
readonly Unavailable: "Unavailable";
|
|
14
|
+
readonly Untouched: "Untouched";
|
|
15
|
+
};
|
|
16
|
+
type ConnectionState = (typeof ConnectionState)[keyof typeof ConnectionState];
|
|
16
17
|
|
|
17
18
|
declare const identity: <T extends unknown>(x: T) => T;
|
|
18
19
|
|
package/dist/index.js
CHANGED
|
@@ -172,7 +172,7 @@ var CrdtManager = class {
|
|
|
172
172
|
}
|
|
173
173
|
_applyDocUpdates(doc, updates, origin) {
|
|
174
174
|
doc.transact(() => {
|
|
175
|
-
doc.batchApplyEncodedState(
|
|
175
|
+
doc.batchApplyEncodedState({ origin, updates });
|
|
176
176
|
}, origin);
|
|
177
177
|
return doc;
|
|
178
178
|
}
|
|
@@ -535,14 +535,13 @@ var UsersManager = class {
|
|
|
535
535
|
};
|
|
536
536
|
|
|
537
537
|
// src/enums.ts
|
|
538
|
-
var ConnectionState =
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
})(ConnectionState || {});
|
|
538
|
+
var ConnectionState = {
|
|
539
|
+
Closed: "Closed",
|
|
540
|
+
Connecting: "Connecting",
|
|
541
|
+
Open: "Open",
|
|
542
|
+
Unavailable: "Unavailable",
|
|
543
|
+
Untouched: "Untouched"
|
|
544
|
+
};
|
|
546
545
|
|
|
547
546
|
// src/PluvRoom.ts
|
|
548
547
|
var ADD_TO_STORAGE_STATE_DEBOUNCE_MS = 1e3;
|
|
@@ -599,7 +598,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
599
598
|
attempts: 0,
|
|
600
599
|
count: 0,
|
|
601
600
|
id: null,
|
|
602
|
-
state:
|
|
601
|
+
state: ConnectionState.Untouched
|
|
603
602
|
},
|
|
604
603
|
webSocket: null
|
|
605
604
|
};
|
|
@@ -608,7 +607,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
608
607
|
this.broadcast = new Proxy(
|
|
609
608
|
(event, data) => __async(this, null, function* () {
|
|
610
609
|
if (!this._state.webSocket) return;
|
|
611
|
-
if (this._state.connection.state !==
|
|
610
|
+
if (this._state.connection.state !== ConnectionState.Open) return;
|
|
612
611
|
const type = event.toString();
|
|
613
612
|
const procedure = this._router._defs.events[type];
|
|
614
613
|
if (!(procedure == null ? void 0 : procedure.config.broadcast)) {
|
|
@@ -765,13 +764,13 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
765
764
|
const params = (_a = args[0]) != null ? _a : {};
|
|
766
765
|
const metadata = params.metadata;
|
|
767
766
|
this._setMetadata(metadata);
|
|
768
|
-
const canConnect = [
|
|
767
|
+
const canConnect = [ConnectionState.Closed, ConnectionState.Unavailable, ConnectionState.Untouched].some(
|
|
769
768
|
(state) => this._state.connection.state === state
|
|
770
769
|
);
|
|
771
770
|
if (!canConnect) return;
|
|
772
771
|
this._clearTimeout(this._timeouts.reconnect);
|
|
773
772
|
this._updateState((oldState) => {
|
|
774
|
-
oldState.connection.state =
|
|
773
|
+
oldState.connection.state = ConnectionState.Connecting;
|
|
775
774
|
return oldState;
|
|
776
775
|
});
|
|
777
776
|
yield this._storageStore.initialize();
|
|
@@ -809,7 +808,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
809
808
|
disconnect() {
|
|
810
809
|
return __async(this, null, function* () {
|
|
811
810
|
if (!this._state.webSocket) return;
|
|
812
|
-
const canDisconnect = [
|
|
811
|
+
const canDisconnect = [ConnectionState.Connecting, ConnectionState.Open].some(
|
|
813
812
|
(state) => this._state.connection.state === state
|
|
814
813
|
);
|
|
815
814
|
if (!canDisconnect) return;
|
|
@@ -818,7 +817,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
818
817
|
this._clearTimeout(this._timeouts.reconnect);
|
|
819
818
|
this._updateState((oldState) => {
|
|
820
819
|
oldState.authorization.token = null;
|
|
821
|
-
oldState.connection.state =
|
|
820
|
+
oldState.connection.state = ConnectionState.Closed;
|
|
822
821
|
oldState.webSocket = null;
|
|
823
822
|
return oldState;
|
|
824
823
|
});
|
|
@@ -857,7 +856,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
857
856
|
_attachWindowListeners() {
|
|
858
857
|
if (typeof window === "undefined") return;
|
|
859
858
|
if (typeof document === "undefined") return;
|
|
860
|
-
this._windowListeners = {
|
|
859
|
+
this._windowListeners = this._windowListeners || {
|
|
861
860
|
onNavigatorOffline: this._onNavigatorOffline.bind(this),
|
|
862
861
|
onNavigatorOnline: this._onNavigatorOnline.bind(this),
|
|
863
862
|
onVisibilityChange: this._onVisibilityChange.bind(this)
|
|
@@ -868,7 +867,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
868
867
|
}
|
|
869
868
|
_attachWsListeners() {
|
|
870
869
|
if (!this._state.webSocket) return;
|
|
871
|
-
this._wsListeners = {
|
|
870
|
+
this._wsListeners = this._wsListeners || {
|
|
872
871
|
onClose: this._onClose.bind(this),
|
|
873
872
|
onError: this._onError.bind(this),
|
|
874
873
|
onMessage: this._onMessage.bind(this),
|
|
@@ -1188,7 +1187,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1188
1187
|
const authError = error instanceof Error ? error : new Error("Authorization failed");
|
|
1189
1188
|
this._listeners.onAuthorizationFail(authError);
|
|
1190
1189
|
this._updateState((oldState) => {
|
|
1191
|
-
oldState.connection.state =
|
|
1190
|
+
oldState.connection.state = ConnectionState.Unavailable;
|
|
1192
1191
|
return oldState;
|
|
1193
1192
|
});
|
|
1194
1193
|
}
|
|
@@ -1212,7 +1211,15 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1212
1211
|
].some((okToRetryCode) => event.code === okToRetryCode);
|
|
1213
1212
|
this._updateState((oldState) => {
|
|
1214
1213
|
oldState.authorization.token = null;
|
|
1215
|
-
oldState.connection.state = shouldRetry ?
|
|
1214
|
+
oldState.connection.state = shouldRetry ? ConnectionState.Unavailable : (
|
|
1215
|
+
/**
|
|
1216
|
+
* !HACK
|
|
1217
|
+
* @description Assume these are not recoverable. We're just going to mark this
|
|
1218
|
+
* as Closed to avoid reconnect attempts.
|
|
1219
|
+
* @date April 28, 2025
|
|
1220
|
+
*/
|
|
1221
|
+
ConnectionState.Closed
|
|
1222
|
+
);
|
|
1216
1223
|
oldState.webSocket = null;
|
|
1217
1224
|
return oldState;
|
|
1218
1225
|
});
|
|
@@ -1280,10 +1287,10 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1280
1287
|
}
|
|
1281
1288
|
}
|
|
1282
1289
|
_onOpen() {
|
|
1283
|
-
if (this._state.connection.state !==
|
|
1290
|
+
if (this._state.connection.state !== ConnectionState.Connecting) return;
|
|
1284
1291
|
this._logDebug("WebSocket connected");
|
|
1285
1292
|
this._updateState((oldState) => {
|
|
1286
|
-
oldState.connection.state =
|
|
1293
|
+
oldState.connection.state = ConnectionState.Open;
|
|
1287
1294
|
return oldState;
|
|
1288
1295
|
});
|
|
1289
1296
|
this._clearInterval(this._intervals.heartbeat);
|
|
@@ -1291,16 +1298,16 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1291
1298
|
}
|
|
1292
1299
|
_onNavigatorOffline() {
|
|
1293
1300
|
return __async(this, null, function* () {
|
|
1294
|
-
if (this._state.connection.state ===
|
|
1301
|
+
if (this._state.connection.state === ConnectionState.Closed) return;
|
|
1295
1302
|
this._updateState((oldState) => {
|
|
1296
|
-
oldState.connection.state =
|
|
1303
|
+
oldState.connection.state = ConnectionState.Unavailable;
|
|
1297
1304
|
return oldState;
|
|
1298
1305
|
});
|
|
1299
1306
|
});
|
|
1300
1307
|
}
|
|
1301
1308
|
_onNavigatorOnline() {
|
|
1302
1309
|
return __async(this, null, function* () {
|
|
1303
|
-
if (this._state.connection.state !==
|
|
1310
|
+
if (this._state.connection.state !== ConnectionState.Unavailable) return;
|
|
1304
1311
|
yield this._reconnect();
|
|
1305
1312
|
});
|
|
1306
1313
|
}
|
|
@@ -1309,12 +1316,12 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1309
1316
|
if (typeof document === "undefined") return;
|
|
1310
1317
|
if (document.visibilityState !== "visible") return;
|
|
1311
1318
|
switch (this._state.connection.state) {
|
|
1312
|
-
case
|
|
1319
|
+
case ConnectionState.Open: {
|
|
1313
1320
|
this._clearInterval(this._intervals.heartbeat);
|
|
1314
1321
|
setInterval(this._heartbeat.bind(this), HEARTBEAT_INTERVAL_MS);
|
|
1315
1322
|
return;
|
|
1316
1323
|
}
|
|
1317
|
-
case
|
|
1324
|
+
case ConnectionState.Unavailable: {
|
|
1318
1325
|
yield this._reconnect();
|
|
1319
1326
|
return;
|
|
1320
1327
|
}
|
|
@@ -1342,8 +1349,8 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1342
1349
|
}
|
|
1343
1350
|
_reconnect() {
|
|
1344
1351
|
return __async(this, null, function* () {
|
|
1345
|
-
if (!this._state.webSocket) return;
|
|
1346
1352
|
this._closeWs();
|
|
1353
|
+
if (this._state.connection.state === ConnectionState.Closed) return;
|
|
1347
1354
|
const metadata = this._lastMetadata;
|
|
1348
1355
|
const params = typeof metadata === "undefined" ? [] : [{ metadata }];
|
|
1349
1356
|
yield this.connect(...params);
|
|
@@ -1508,7 +1515,7 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1508
1515
|
attempts: 0,
|
|
1509
1516
|
count: 1,
|
|
1510
1517
|
id: null,
|
|
1511
|
-
state:
|
|
1518
|
+
state: ConnectionState.Untouched
|
|
1512
1519
|
},
|
|
1513
1520
|
webSocket: null
|
|
1514
1521
|
};
|
|
@@ -1519,7 +1526,7 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1519
1526
|
this.broadcast = new Proxy(
|
|
1520
1527
|
(event, data) => __async(this, null, function* () {
|
|
1521
1528
|
if (!this._state.webSocket) return;
|
|
1522
|
-
if (this._state.connection.state !==
|
|
1529
|
+
if (this._state.connection.state !== ConnectionState.Open) return;
|
|
1523
1530
|
const type = event.toString();
|
|
1524
1531
|
const procedure = this._router._defs.events[type];
|
|
1525
1532
|
if (!(procedure == null ? void 0 : procedure.config.broadcast)) {
|
package/dist/index.mjs
CHANGED
|
@@ -141,7 +141,7 @@ var CrdtManager = class {
|
|
|
141
141
|
}
|
|
142
142
|
_applyDocUpdates(doc, updates, origin) {
|
|
143
143
|
doc.transact(() => {
|
|
144
|
-
doc.batchApplyEncodedState(
|
|
144
|
+
doc.batchApplyEncodedState({ origin, updates });
|
|
145
145
|
}, origin);
|
|
146
146
|
return doc;
|
|
147
147
|
}
|
|
@@ -504,14 +504,13 @@ var UsersManager = class {
|
|
|
504
504
|
};
|
|
505
505
|
|
|
506
506
|
// src/enums.ts
|
|
507
|
-
var ConnectionState =
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
})(ConnectionState || {});
|
|
507
|
+
var ConnectionState = {
|
|
508
|
+
Closed: "Closed",
|
|
509
|
+
Connecting: "Connecting",
|
|
510
|
+
Open: "Open",
|
|
511
|
+
Unavailable: "Unavailable",
|
|
512
|
+
Untouched: "Untouched"
|
|
513
|
+
};
|
|
515
514
|
|
|
516
515
|
// src/PluvRoom.ts
|
|
517
516
|
var ADD_TO_STORAGE_STATE_DEBOUNCE_MS = 1e3;
|
|
@@ -568,7 +567,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
568
567
|
attempts: 0,
|
|
569
568
|
count: 0,
|
|
570
569
|
id: null,
|
|
571
|
-
state:
|
|
570
|
+
state: ConnectionState.Untouched
|
|
572
571
|
},
|
|
573
572
|
webSocket: null
|
|
574
573
|
};
|
|
@@ -577,7 +576,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
577
576
|
this.broadcast = new Proxy(
|
|
578
577
|
(event, data) => __async(this, null, function* () {
|
|
579
578
|
if (!this._state.webSocket) return;
|
|
580
|
-
if (this._state.connection.state !==
|
|
579
|
+
if (this._state.connection.state !== ConnectionState.Open) return;
|
|
581
580
|
const type = event.toString();
|
|
582
581
|
const procedure = this._router._defs.events[type];
|
|
583
582
|
if (!(procedure == null ? void 0 : procedure.config.broadcast)) {
|
|
@@ -734,13 +733,13 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
734
733
|
const params = (_a = args[0]) != null ? _a : {};
|
|
735
734
|
const metadata = params.metadata;
|
|
736
735
|
this._setMetadata(metadata);
|
|
737
|
-
const canConnect = [
|
|
736
|
+
const canConnect = [ConnectionState.Closed, ConnectionState.Unavailable, ConnectionState.Untouched].some(
|
|
738
737
|
(state) => this._state.connection.state === state
|
|
739
738
|
);
|
|
740
739
|
if (!canConnect) return;
|
|
741
740
|
this._clearTimeout(this._timeouts.reconnect);
|
|
742
741
|
this._updateState((oldState) => {
|
|
743
|
-
oldState.connection.state =
|
|
742
|
+
oldState.connection.state = ConnectionState.Connecting;
|
|
744
743
|
return oldState;
|
|
745
744
|
});
|
|
746
745
|
yield this._storageStore.initialize();
|
|
@@ -778,7 +777,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
778
777
|
disconnect() {
|
|
779
778
|
return __async(this, null, function* () {
|
|
780
779
|
if (!this._state.webSocket) return;
|
|
781
|
-
const canDisconnect = [
|
|
780
|
+
const canDisconnect = [ConnectionState.Connecting, ConnectionState.Open].some(
|
|
782
781
|
(state) => this._state.connection.state === state
|
|
783
782
|
);
|
|
784
783
|
if (!canDisconnect) return;
|
|
@@ -787,7 +786,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
787
786
|
this._clearTimeout(this._timeouts.reconnect);
|
|
788
787
|
this._updateState((oldState) => {
|
|
789
788
|
oldState.authorization.token = null;
|
|
790
|
-
oldState.connection.state =
|
|
789
|
+
oldState.connection.state = ConnectionState.Closed;
|
|
791
790
|
oldState.webSocket = null;
|
|
792
791
|
return oldState;
|
|
793
792
|
});
|
|
@@ -826,7 +825,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
826
825
|
_attachWindowListeners() {
|
|
827
826
|
if (typeof window === "undefined") return;
|
|
828
827
|
if (typeof document === "undefined") return;
|
|
829
|
-
this._windowListeners = {
|
|
828
|
+
this._windowListeners = this._windowListeners || {
|
|
830
829
|
onNavigatorOffline: this._onNavigatorOffline.bind(this),
|
|
831
830
|
onNavigatorOnline: this._onNavigatorOnline.bind(this),
|
|
832
831
|
onVisibilityChange: this._onVisibilityChange.bind(this)
|
|
@@ -837,7 +836,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
837
836
|
}
|
|
838
837
|
_attachWsListeners() {
|
|
839
838
|
if (!this._state.webSocket) return;
|
|
840
|
-
this._wsListeners = {
|
|
839
|
+
this._wsListeners = this._wsListeners || {
|
|
841
840
|
onClose: this._onClose.bind(this),
|
|
842
841
|
onError: this._onError.bind(this),
|
|
843
842
|
onMessage: this._onMessage.bind(this),
|
|
@@ -1157,7 +1156,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1157
1156
|
const authError = error instanceof Error ? error : new Error("Authorization failed");
|
|
1158
1157
|
this._listeners.onAuthorizationFail(authError);
|
|
1159
1158
|
this._updateState((oldState) => {
|
|
1160
|
-
oldState.connection.state =
|
|
1159
|
+
oldState.connection.state = ConnectionState.Unavailable;
|
|
1161
1160
|
return oldState;
|
|
1162
1161
|
});
|
|
1163
1162
|
}
|
|
@@ -1181,7 +1180,15 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1181
1180
|
].some((okToRetryCode) => event.code === okToRetryCode);
|
|
1182
1181
|
this._updateState((oldState) => {
|
|
1183
1182
|
oldState.authorization.token = null;
|
|
1184
|
-
oldState.connection.state = shouldRetry ?
|
|
1183
|
+
oldState.connection.state = shouldRetry ? ConnectionState.Unavailable : (
|
|
1184
|
+
/**
|
|
1185
|
+
* !HACK
|
|
1186
|
+
* @description Assume these are not recoverable. We're just going to mark this
|
|
1187
|
+
* as Closed to avoid reconnect attempts.
|
|
1188
|
+
* @date April 28, 2025
|
|
1189
|
+
*/
|
|
1190
|
+
ConnectionState.Closed
|
|
1191
|
+
);
|
|
1185
1192
|
oldState.webSocket = null;
|
|
1186
1193
|
return oldState;
|
|
1187
1194
|
});
|
|
@@ -1249,10 +1256,10 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1249
1256
|
}
|
|
1250
1257
|
}
|
|
1251
1258
|
_onOpen() {
|
|
1252
|
-
if (this._state.connection.state !==
|
|
1259
|
+
if (this._state.connection.state !== ConnectionState.Connecting) return;
|
|
1253
1260
|
this._logDebug("WebSocket connected");
|
|
1254
1261
|
this._updateState((oldState) => {
|
|
1255
|
-
oldState.connection.state =
|
|
1262
|
+
oldState.connection.state = ConnectionState.Open;
|
|
1256
1263
|
return oldState;
|
|
1257
1264
|
});
|
|
1258
1265
|
this._clearInterval(this._intervals.heartbeat);
|
|
@@ -1260,16 +1267,16 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1260
1267
|
}
|
|
1261
1268
|
_onNavigatorOffline() {
|
|
1262
1269
|
return __async(this, null, function* () {
|
|
1263
|
-
if (this._state.connection.state ===
|
|
1270
|
+
if (this._state.connection.state === ConnectionState.Closed) return;
|
|
1264
1271
|
this._updateState((oldState) => {
|
|
1265
|
-
oldState.connection.state =
|
|
1272
|
+
oldState.connection.state = ConnectionState.Unavailable;
|
|
1266
1273
|
return oldState;
|
|
1267
1274
|
});
|
|
1268
1275
|
});
|
|
1269
1276
|
}
|
|
1270
1277
|
_onNavigatorOnline() {
|
|
1271
1278
|
return __async(this, null, function* () {
|
|
1272
|
-
if (this._state.connection.state !==
|
|
1279
|
+
if (this._state.connection.state !== ConnectionState.Unavailable) return;
|
|
1273
1280
|
yield this._reconnect();
|
|
1274
1281
|
});
|
|
1275
1282
|
}
|
|
@@ -1278,12 +1285,12 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1278
1285
|
if (typeof document === "undefined") return;
|
|
1279
1286
|
if (document.visibilityState !== "visible") return;
|
|
1280
1287
|
switch (this._state.connection.state) {
|
|
1281
|
-
case
|
|
1288
|
+
case ConnectionState.Open: {
|
|
1282
1289
|
this._clearInterval(this._intervals.heartbeat);
|
|
1283
1290
|
setInterval(this._heartbeat.bind(this), HEARTBEAT_INTERVAL_MS);
|
|
1284
1291
|
return;
|
|
1285
1292
|
}
|
|
1286
|
-
case
|
|
1293
|
+
case ConnectionState.Unavailable: {
|
|
1287
1294
|
yield this._reconnect();
|
|
1288
1295
|
return;
|
|
1289
1296
|
}
|
|
@@ -1311,8 +1318,8 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
1311
1318
|
}
|
|
1312
1319
|
_reconnect() {
|
|
1313
1320
|
return __async(this, null, function* () {
|
|
1314
|
-
if (!this._state.webSocket) return;
|
|
1315
1321
|
this._closeWs();
|
|
1322
|
+
if (this._state.connection.state === ConnectionState.Closed) return;
|
|
1316
1323
|
const metadata = this._lastMetadata;
|
|
1317
1324
|
const params = typeof metadata === "undefined" ? [] : [{ metadata }];
|
|
1318
1325
|
yield this.connect(...params);
|
|
@@ -1477,7 +1484,7 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1477
1484
|
attempts: 0,
|
|
1478
1485
|
count: 1,
|
|
1479
1486
|
id: null,
|
|
1480
|
-
state:
|
|
1487
|
+
state: ConnectionState.Untouched
|
|
1481
1488
|
},
|
|
1482
1489
|
webSocket: null
|
|
1483
1490
|
};
|
|
@@ -1488,7 +1495,7 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1488
1495
|
this.broadcast = new Proxy(
|
|
1489
1496
|
(event, data) => __async(this, null, function* () {
|
|
1490
1497
|
if (!this._state.webSocket) return;
|
|
1491
|
-
if (this._state.connection.state !==
|
|
1498
|
+
if (this._state.connection.state !== ConnectionState.Open) return;
|
|
1492
1499
|
const type = event.toString();
|
|
1493
1500
|
const procedure = this._router._defs.events[type];
|
|
1494
1501
|
if (!(procedure == null ? void 0 : procedure.config.broadcast)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "@pluv/io frontend client",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"wonka": "^6.3.5",
|
|
21
|
-
"@pluv/crdt": "^0.
|
|
22
|
-
"@pluv/types": "^0.
|
|
21
|
+
"@pluv/crdt": "^0.44.0",
|
|
22
|
+
"@pluv/types": "^0.44.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"eslint": "^9.25.1",
|
|
26
26
|
"tsup": "^8.4.0",
|
|
27
27
|
"typescript": "^5.8.3",
|
|
28
|
-
"@pluv/tsconfig": "^0.
|
|
29
|
-
"eslint-config-pluv": "^0.
|
|
28
|
+
"@pluv/tsconfig": "^0.44.0",
|
|
29
|
+
"eslint-config-pluv": "^0.44.0"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
package/src/CrdtManager.ts
CHANGED
|
@@ -93,7 +93,7 @@ export class CrdtManager<TStorage extends Record<string, CrdtType<any, any>>> {
|
|
|
93
93
|
origin?: string,
|
|
94
94
|
): AbstractCrdtDoc<TStorage> {
|
|
95
95
|
doc.transact(() => {
|
|
96
|
-
doc.batchApplyEncodedState(
|
|
96
|
+
doc.batchApplyEncodedState({ origin, updates });
|
|
97
97
|
}, origin);
|
|
98
98
|
|
|
99
99
|
return doc;
|
package/src/PluvRoom.ts
CHANGED
|
@@ -363,7 +363,7 @@ export class PluvRoom<
|
|
|
363
363
|
|
|
364
364
|
this._setMetadata(metadata);
|
|
365
365
|
|
|
366
|
-
const canConnect = [ConnectionState.Closed, ConnectionState.Untouched].some(
|
|
366
|
+
const canConnect = [ConnectionState.Closed, ConnectionState.Unavailable, ConnectionState.Untouched].some(
|
|
367
367
|
(state) => this._state.connection.state === state,
|
|
368
368
|
);
|
|
369
369
|
|
|
@@ -615,7 +615,7 @@ export class PluvRoom<
|
|
|
615
615
|
if (typeof window === "undefined") return;
|
|
616
616
|
if (typeof document === "undefined") return;
|
|
617
617
|
|
|
618
|
-
this._windowListeners = {
|
|
618
|
+
this._windowListeners = this._windowListeners || {
|
|
619
619
|
onNavigatorOffline: this._onNavigatorOffline.bind(this),
|
|
620
620
|
onNavigatorOnline: this._onNavigatorOnline.bind(this),
|
|
621
621
|
onVisibilityChange: this._onVisibilityChange.bind(this),
|
|
@@ -629,7 +629,7 @@ export class PluvRoom<
|
|
|
629
629
|
private _attachWsListeners(): void {
|
|
630
630
|
if (!this._state.webSocket) return;
|
|
631
631
|
|
|
632
|
-
this._wsListeners = {
|
|
632
|
+
this._wsListeners = this._wsListeners || {
|
|
633
633
|
onClose: this._onClose.bind(this),
|
|
634
634
|
onError: this._onError.bind(this),
|
|
635
635
|
onMessage: this._onMessage.bind(this),
|
|
@@ -1152,7 +1152,15 @@ export class PluvRoom<
|
|
|
1152
1152
|
|
|
1153
1153
|
this._updateState((oldState) => {
|
|
1154
1154
|
oldState.authorization.token = null;
|
|
1155
|
-
oldState.connection.state = shouldRetry
|
|
1155
|
+
oldState.connection.state = shouldRetry
|
|
1156
|
+
? ConnectionState.Unavailable
|
|
1157
|
+
: /**
|
|
1158
|
+
* !HACK
|
|
1159
|
+
* @description Assume these are not recoverable. We're just going to mark this
|
|
1160
|
+
* as Closed to avoid reconnect attempts.
|
|
1161
|
+
* @date April 28, 2025
|
|
1162
|
+
*/
|
|
1163
|
+
ConnectionState.Closed;
|
|
1156
1164
|
oldState.webSocket = null;
|
|
1157
1165
|
|
|
1158
1166
|
return oldState;
|
|
@@ -1314,10 +1322,16 @@ export class PluvRoom<
|
|
|
1314
1322
|
}
|
|
1315
1323
|
|
|
1316
1324
|
private async _reconnect(): Promise<void> {
|
|
1317
|
-
if (!this._state.webSocket) return;
|
|
1318
|
-
|
|
1319
1325
|
this._closeWs();
|
|
1320
1326
|
|
|
1327
|
+
/**
|
|
1328
|
+
* @description User has manually closed this connection. We're not going to retry, since
|
|
1329
|
+
* the user probably intends for this to stay closed. They will need to invoke connect
|
|
1330
|
+
* themselves.
|
|
1331
|
+
* @date April 28, 2025
|
|
1332
|
+
*/
|
|
1333
|
+
if (this._state.connection.state === ConnectionState.Closed) return;
|
|
1334
|
+
|
|
1321
1335
|
const metadata = this._lastMetadata;
|
|
1322
1336
|
const params = (typeof metadata === "undefined" ? [] : [{ metadata }]) as RoomConnectParams<TMetadata>;
|
|
1323
1337
|
|
package/src/enums.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export
|
|
2
|
-
Closed
|
|
3
|
-
Connecting
|
|
4
|
-
Open
|
|
5
|
-
Unavailable
|
|
6
|
-
Untouched
|
|
7
|
-
}
|
|
1
|
+
export const ConnectionState = {
|
|
2
|
+
Closed: "Closed",
|
|
3
|
+
Connecting: "Connecting",
|
|
4
|
+
Open: "Open",
|
|
5
|
+
Unavailable: "Unavailable",
|
|
6
|
+
Untouched: "Untouched",
|
|
7
|
+
} as const;
|
|
8
|
+
|
|
9
|
+
export type ConnectionState = (typeof ConnectionState)[keyof typeof ConnectionState];
|