@pluv/io 0.40.2 → 0.41.1
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 +9 -9
- package/CHANGELOG.md +69 -0
- package/dist/index.d.mts +30 -21
- package/dist/index.d.ts +30 -21
- package/dist/index.js +198 -75
- package/dist/index.mjs +198 -75
- package/package.json +7 -7
- package/src/AbstractPlatform.ts +3 -3
- package/src/AbstractWebSocket.ts +3 -20
- package/src/IORoom.ts +248 -65
- package/src/PluvServer.ts +39 -12
- package/src/authorize.ts +4 -4
- package/src/constants.ts +3 -0
- package/src/types.ts +4 -8
- package/src/version.generated.ts +1 -1
- package/tsconfig.json +5 -1
package/dist/index.js
CHANGED
|
@@ -244,28 +244,12 @@ var AbstractWebSocket = class {
|
|
|
244
244
|
this.CLOSING = 2;
|
|
245
245
|
/** The connection is closed. */
|
|
246
246
|
this.CLOSED = 3;
|
|
247
|
-
this._user = null;
|
|
248
247
|
const { persistence, platform, room } = config;
|
|
249
248
|
this.persistence = persistence;
|
|
250
249
|
this._platform = platform;
|
|
251
250
|
this.room = room;
|
|
252
251
|
this.webSocket = webSocket;
|
|
253
252
|
}
|
|
254
|
-
getSession() {
|
|
255
|
-
return __async(this, null, function* () {
|
|
256
|
-
var _a;
|
|
257
|
-
const sessionId = this.sessionId;
|
|
258
|
-
const state = this.state;
|
|
259
|
-
const room = state.room;
|
|
260
|
-
const user = (_a = this._user) != null ? _a : yield this.persistence.getUser(room, sessionId);
|
|
261
|
-
this._user = user;
|
|
262
|
-
return __spreadProps(__spreadValues({}, state), {
|
|
263
|
-
id: sessionId,
|
|
264
|
-
user,
|
|
265
|
-
webSocket: this
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
253
|
handleError(params) {
|
|
270
254
|
var _a, _b, _c;
|
|
271
255
|
const { error, message: _message, room, session } = params;
|
|
@@ -403,14 +387,19 @@ var import_crdt = require("@pluv/crdt");
|
|
|
403
387
|
var import_kleur = __toESM(require("kleur"));
|
|
404
388
|
|
|
405
389
|
// src/constants.ts
|
|
390
|
+
var GARBAGE_COLLECT_INTERVAL_MS = 6e4;
|
|
391
|
+
var MAX_PRESENCE_SIZE_BYTES = 512;
|
|
392
|
+
var MAX_USER_SIZE_BYTES = 512;
|
|
406
393
|
var PING_TIMEOUT_MS = 3e4;
|
|
407
394
|
|
|
408
395
|
// src/IORoom.ts
|
|
409
396
|
var IORoom = class {
|
|
410
397
|
constructor(id, config) {
|
|
398
|
+
this._lastGarbageCollectMs = -1 * (GARBAGE_COLLECT_INTERVAL_MS + 1);
|
|
411
399
|
this._uninitialize = null;
|
|
412
400
|
this._authorize = null;
|
|
413
401
|
this._sessions = /* @__PURE__ */ new Map();
|
|
402
|
+
this._userSessionss = /* @__PURE__ */ new Map();
|
|
414
403
|
const {
|
|
415
404
|
_meta,
|
|
416
405
|
authorize: authorize2,
|
|
@@ -440,12 +429,15 @@ var IORoom = class {
|
|
|
440
429
|
if (authorize2) this._authorize = authorize2;
|
|
441
430
|
const webSockets = this._platform.getWebSockets();
|
|
442
431
|
webSockets.forEach((webSocket) => {
|
|
432
|
+
var _a;
|
|
443
433
|
const deserialized = this._platform.getSerializedState(webSocket);
|
|
444
434
|
const sessionId = this._platform.getSessionId(webSocket);
|
|
445
435
|
if (!deserialized) return;
|
|
446
436
|
if (typeof sessionId !== "string") return;
|
|
447
437
|
const pluvWs = this._platform.convertWebSocket(webSocket, { room: this.id });
|
|
448
438
|
this._sessions.set(sessionId, pluvWs);
|
|
439
|
+
const userId = (_a = pluvWs.session.user) == null ? void 0 : _a.id;
|
|
440
|
+
if (!!userId) this._addUserSession(userId, sessionId);
|
|
449
441
|
});
|
|
450
442
|
const { doc, uninitialize } = this._initialize();
|
|
451
443
|
this._doc = doc;
|
|
@@ -503,6 +495,16 @@ var IORoom = class {
|
|
|
503
495
|
yield this._emitQuitters();
|
|
504
496
|
});
|
|
505
497
|
}
|
|
498
|
+
/**
|
|
499
|
+
* @description The IORoom will garbage collect occasionally as connections ping/pong the
|
|
500
|
+
* server
|
|
501
|
+
*/
|
|
502
|
+
garbageCollect() {
|
|
503
|
+
return __async(this, null, function* () {
|
|
504
|
+
this._lastGarbageCollectMs = Date.now();
|
|
505
|
+
this._emitQuitters();
|
|
506
|
+
});
|
|
507
|
+
}
|
|
506
508
|
getSize() {
|
|
507
509
|
const currentTime = (/* @__PURE__ */ new Date()).getTime();
|
|
508
510
|
return Array.from(this._sessions.values()).reduce((count, pluvWs) => {
|
|
@@ -551,19 +553,25 @@ var IORoom = class {
|
|
|
551
553
|
const user = yield this._getAuthorizedUser(token, _options);
|
|
552
554
|
const ioAuthorize = this._getIOAuthorize(_options);
|
|
553
555
|
const isUnauthorized = !!ioAuthorize && !user;
|
|
554
|
-
const isTokenInUse = !!user && (yield this._getSessions().then((sessions) => sessions.some((session) => {
|
|
555
|
-
var _a2;
|
|
556
|
-
return ((_a2 = session.user) == null ? void 0 : _a2.id) === user.id;
|
|
557
|
-
})));
|
|
558
556
|
const pluvWs = this._platform.convertWebSocket(webSocket, { room: this.id });
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
if (isUnauthorized || isTokenInUse) {
|
|
562
|
-
this._logDebug(`${import_kleur.default.blue("Authorization failed for connection:")} ${pluvWs.sessionId}`);
|
|
557
|
+
if (isUnauthorized) {
|
|
558
|
+
this._logDebug(`${import_kleur.default.blue("Authorization failed for connection")}`);
|
|
563
559
|
pluvWs.handleError({ error: new Error("Not authorized"), room: this.id });
|
|
564
560
|
pluvWs.close(3e3, "WebSocket unauthorized.");
|
|
565
561
|
return;
|
|
566
562
|
}
|
|
563
|
+
if (!!user) {
|
|
564
|
+
const latest = this._getLatestPresence(user.id);
|
|
565
|
+
const prevState = pluvWs.state;
|
|
566
|
+
pluvWs.user = user;
|
|
567
|
+
this._platform.setSerializedState(pluvWs, __spreadProps(__spreadValues({}, prevState), {
|
|
568
|
+
presence: latest.presence,
|
|
569
|
+
timers: __spreadProps(__spreadValues({}, prevState.timers), { presence: latest.timer })
|
|
570
|
+
}));
|
|
571
|
+
this._addUserSession(user.id, pluvWs.sessionId);
|
|
572
|
+
}
|
|
573
|
+
this._logDebug(`${import_kleur.default.blue(`Registering connection for room ${this.id}:`)} ${pluvWs.sessionId}`);
|
|
574
|
+
yield this._platform.acceptWebSocket(pluvWs);
|
|
567
575
|
this._sessions.set(pluvWs.sessionId, pluvWs);
|
|
568
576
|
yield this._platform.persistence.addUser(this.id, pluvWs.sessionId, user != null ? user : {});
|
|
569
577
|
if (this._platform._config.registrationMode === "attached") {
|
|
@@ -574,17 +582,24 @@ var IORoom = class {
|
|
|
574
582
|
pluvWs.addEventListener("message", onMessage);
|
|
575
583
|
}
|
|
576
584
|
yield this._emitRegistered(pluvWs);
|
|
577
|
-
this._logDebug(`${import_kleur.default.blue(`Registered connection for room ${this.id}:`)} ${pluvWs.sessionId}`);
|
|
578
585
|
const size = this.getSize();
|
|
586
|
+
this._logDebug(`${import_kleur.default.blue(`Registered connection for room ${this.id}:`)} ${pluvWs.sessionId}`);
|
|
579
587
|
this._logDebug(`${import_kleur.default.blue(`Room ${this.id} size:`)} ${size}`);
|
|
580
588
|
});
|
|
581
589
|
}
|
|
590
|
+
_addUserSession(userId, sessionId) {
|
|
591
|
+
var _a;
|
|
592
|
+
const set = (_a = this._userSessionss.get(userId)) != null ? _a : /* @__PURE__ */ new Set();
|
|
593
|
+
const updated = set.add(sessionId);
|
|
594
|
+
this._userSessionss.set(userId, updated);
|
|
595
|
+
return updated;
|
|
596
|
+
}
|
|
582
597
|
_broadcast(params) {
|
|
583
598
|
return __async(this, null, function* () {
|
|
584
599
|
var _a, _b, _c;
|
|
585
600
|
const { message, senderId } = params;
|
|
586
601
|
const sender = senderId ? (_a = this._sessions.get(senderId)) != null ? _a : null : null;
|
|
587
|
-
const session = (_b =
|
|
602
|
+
const session = (_b = sender == null ? void 0 : sender.session) != null ? _b : null;
|
|
588
603
|
const user = (_c = session == null ? void 0 : session.user) != null ? _c : null;
|
|
589
604
|
if (typeof senderId !== "string") return;
|
|
590
605
|
this._platform.pubSub.publish(this.id, __spreadValues({
|
|
@@ -606,15 +621,18 @@ var IORoom = class {
|
|
|
606
621
|
message: { type: "$exit", data: { sessionId } },
|
|
607
622
|
senderId: sessionId
|
|
608
623
|
});
|
|
624
|
+
const session = webSocket.session;
|
|
625
|
+
const user = session.user;
|
|
626
|
+
if (!!user) this._removeUserSession(user.id, sessionId);
|
|
609
627
|
try {
|
|
610
|
-
const
|
|
628
|
+
const doc = yield this._doc;
|
|
611
629
|
const encodedState = doc.getEncodedState();
|
|
612
630
|
yield Promise.resolve(
|
|
613
631
|
this._listeners.onUserDisconnected({
|
|
614
632
|
context: this._context,
|
|
615
633
|
encodedState,
|
|
616
634
|
room: this.id,
|
|
617
|
-
user
|
|
635
|
+
user
|
|
618
636
|
})
|
|
619
637
|
);
|
|
620
638
|
} catch (error) {
|
|
@@ -645,10 +663,21 @@ var IORoom = class {
|
|
|
645
663
|
}
|
|
646
664
|
_emitRegistered(pluvWs) {
|
|
647
665
|
return __async(this, null, function* () {
|
|
648
|
-
const session =
|
|
666
|
+
const session = pluvWs.session;
|
|
649
667
|
const sessionId = session.id;
|
|
668
|
+
const presence = session.presence;
|
|
650
669
|
const user = session.user;
|
|
651
|
-
yield this._sendSelfMessage(
|
|
670
|
+
yield this._sendSelfMessage(
|
|
671
|
+
{
|
|
672
|
+
type: "$registered",
|
|
673
|
+
data: {
|
|
674
|
+
presence,
|
|
675
|
+
sessionId,
|
|
676
|
+
timers: { presence: session.timers.presence }
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
{ sessionId, user }
|
|
680
|
+
);
|
|
652
681
|
try {
|
|
653
682
|
const doc = yield this._doc;
|
|
654
683
|
const encodedState = doc.getEncodedState();
|
|
@@ -723,6 +752,27 @@ var IORoom = class {
|
|
|
723
752
|
if (typeof this._authorize === "function") return this._authorize(options);
|
|
724
753
|
return this._authorize;
|
|
725
754
|
}
|
|
755
|
+
_getLatestPresence(userId) {
|
|
756
|
+
var _a, _b;
|
|
757
|
+
if (!this._authorize) return { timer: null, presence: null };
|
|
758
|
+
const sessionIds = Array.from((_b = (_a = this._userSessionss.get(userId)) == null ? void 0 : _a.values()) != null ? _b : []);
|
|
759
|
+
if (!sessionIds.length) return { timer: null, presence: null };
|
|
760
|
+
return sessionIds.reduce(
|
|
761
|
+
(state, sessionId) => {
|
|
762
|
+
var _a2, _b2;
|
|
763
|
+
const pluvWs = (_a2 = this._sessions.get(sessionId)) != null ? _a2 : null;
|
|
764
|
+
if (!pluvWs) return state;
|
|
765
|
+
const session = pluvWs.session;
|
|
766
|
+
const presence = session.presence;
|
|
767
|
+
const timer = session.timers.presence;
|
|
768
|
+
if (((_b2 = session.user) == null ? void 0 : _b2.id) !== userId) return state;
|
|
769
|
+
if (typeof state.timer !== "number") return { presence, timer };
|
|
770
|
+
if (typeof timer !== "number") return state;
|
|
771
|
+
return timer > state.timer ? { presence, timer } : state;
|
|
772
|
+
},
|
|
773
|
+
{ presence: null, timer: null }
|
|
774
|
+
);
|
|
775
|
+
}
|
|
726
776
|
_getProcedure(message) {
|
|
727
777
|
var _a;
|
|
728
778
|
return (_a = this._router._defs.events[message.type]) != null ? _a : null;
|
|
@@ -733,19 +783,13 @@ var IORoom = class {
|
|
|
733
783
|
return procedure.config.input ? procedure.config.input.parse(message.data) : message.data;
|
|
734
784
|
}
|
|
735
785
|
_getSession(webSocket) {
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
return yield pluvWs.getSession();
|
|
740
|
-
});
|
|
786
|
+
const pluvWs = this._getAbstractWs(webSocket);
|
|
787
|
+
if (!pluvWs) throw new Error("Session could not be found");
|
|
788
|
+
return pluvWs.session;
|
|
741
789
|
}
|
|
742
790
|
_getSessions() {
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
return yield pluvWs.getSession();
|
|
746
|
-
}));
|
|
747
|
-
return yield Promise.all(promises);
|
|
748
|
-
});
|
|
791
|
+
const sessions = Array.from(this._sessions.values()).map((pluvWs) => pluvWs.session);
|
|
792
|
+
return sessions;
|
|
749
793
|
}
|
|
750
794
|
_initialize() {
|
|
751
795
|
const promise = (() => __async(this, null, function* () {
|
|
@@ -818,17 +862,31 @@ var IORoom = class {
|
|
|
818
862
|
if (!(yield this._initialized)) return;
|
|
819
863
|
const pluvWs = this._getAbstractWs(webSocket);
|
|
820
864
|
if (!pluvWs) throw new Error("Could not get session");
|
|
821
|
-
const
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
865
|
+
const session = this._getSession(pluvWs);
|
|
866
|
+
const sessions = this._getSessions();
|
|
867
|
+
const setPresence = (params) => {
|
|
868
|
+
this._setPresence.bind(this)(params);
|
|
869
|
+
};
|
|
825
870
|
const doc = yield this._doc;
|
|
826
871
|
const eventContext = {
|
|
827
872
|
context: this._context,
|
|
828
873
|
doc,
|
|
874
|
+
garbageCollect: () => __async(this, null, function* () {
|
|
875
|
+
yield this.garbageCollect();
|
|
876
|
+
}),
|
|
877
|
+
get presence() {
|
|
878
|
+
return session.presence;
|
|
879
|
+
},
|
|
880
|
+
set presence(presence) {
|
|
881
|
+
var _a2;
|
|
882
|
+
const sessionId2 = (_a2 = this.session) == null ? void 0 : _a2.id;
|
|
883
|
+
if (!sessionId2) return;
|
|
884
|
+
setPresence({ presence, sessionId: sessionId2, timer: this.time });
|
|
885
|
+
},
|
|
829
886
|
room: this.id,
|
|
830
887
|
session,
|
|
831
|
-
sessions
|
|
888
|
+
sessions,
|
|
889
|
+
time: (/* @__PURE__ */ new Date()).getTime()
|
|
832
890
|
};
|
|
833
891
|
if (pluvWs.state.quit) {
|
|
834
892
|
yield this._closeWebSockets([pluvWs]).catch(() => null);
|
|
@@ -874,22 +932,20 @@ var IORoom = class {
|
|
|
874
932
|
]).then((_0) => __async(this, [_0], function* ([broadcast, self, sync]) {
|
|
875
933
|
const handleBroadcast = () => __async(this, null, function* () {
|
|
876
934
|
if (!broadcast) return;
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
);
|
|
935
|
+
const messages = Object.entries(broadcast).map((_02) => __async(this, [_02], function* ([type, data]) {
|
|
936
|
+
yield this._broadcast({
|
|
937
|
+
message: { data, type },
|
|
938
|
+
senderId: sessionId
|
|
939
|
+
});
|
|
940
|
+
}));
|
|
941
|
+
yield Promise.all(messages);
|
|
885
942
|
});
|
|
886
943
|
const handleSelf = () => __async(this, null, function* () {
|
|
887
944
|
if (!self) return;
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
);
|
|
945
|
+
const messages = Object.entries(self).map((_02) => __async(this, [_02], function* ([type, data]) {
|
|
946
|
+
yield this._sendSelfMessage({ data, type }, { sessionId, user });
|
|
947
|
+
}));
|
|
948
|
+
yield Promise.all(messages);
|
|
893
949
|
});
|
|
894
950
|
const handleSync = () => __async(this, null, function* () {
|
|
895
951
|
if (!sync) return;
|
|
@@ -899,11 +955,10 @@ var IORoom = class {
|
|
|
899
955
|
room: this.id,
|
|
900
956
|
user
|
|
901
957
|
}, message));
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
);
|
|
958
|
+
const messages = Object.entries(sync).map((_02) => __async(this, [_02], function* ([type, data]) {
|
|
959
|
+
yield this._sendSelfMessage({ data, type }, { sessionId, user });
|
|
960
|
+
}));
|
|
961
|
+
yield Promise.all(messages);
|
|
907
962
|
});
|
|
908
963
|
yield Promise.all([handleBroadcast(), handleSelf(), handleSync()]);
|
|
909
964
|
}));
|
|
@@ -920,6 +975,36 @@ var IORoom = class {
|
|
|
920
975
|
return null;
|
|
921
976
|
}
|
|
922
977
|
}
|
|
978
|
+
_setPresence(params) {
|
|
979
|
+
var _a, _b;
|
|
980
|
+
const { presence, sessionId, timer: _timer } = params;
|
|
981
|
+
const timer = _timer != null ? _timer : (/* @__PURE__ */ new Date()).getTime();
|
|
982
|
+
const pluvWs = (_a = this._sessions.get(sessionId)) != null ? _a : null;
|
|
983
|
+
if (!pluvWs) return;
|
|
984
|
+
const wsSession = pluvWs.session;
|
|
985
|
+
const user = wsSession.user;
|
|
986
|
+
const sessionIds = user ? /* @__PURE__ */ new Set([...(_b = this._userSessionss.get(user.id)) != null ? _b : [], sessionId]) : /* @__PURE__ */ new Set([sessionId]);
|
|
987
|
+
sessionIds.forEach((sId) => {
|
|
988
|
+
const pWs = this._sessions.get(sId);
|
|
989
|
+
const session = pWs == null ? void 0 : pWs.session;
|
|
990
|
+
if (!session) return;
|
|
991
|
+
const prevState = session.webSocket.state;
|
|
992
|
+
this._platform.setSerializedState(session.webSocket, __spreadProps(__spreadValues({}, prevState), {
|
|
993
|
+
presence,
|
|
994
|
+
timers: __spreadProps(__spreadValues({}, prevState.timers), {
|
|
995
|
+
presence: timer
|
|
996
|
+
})
|
|
997
|
+
}));
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
_removeUserSession(userId, sessionId) {
|
|
1001
|
+
const set = this._userSessionss.get(userId);
|
|
1002
|
+
if (!set) return null;
|
|
1003
|
+
set.delete(sessionId);
|
|
1004
|
+
if (!!set.size) return set;
|
|
1005
|
+
this._userSessionss.delete(userId);
|
|
1006
|
+
return set;
|
|
1007
|
+
}
|
|
923
1008
|
_sendMessage(pluvWs, message) {
|
|
924
1009
|
return __async(this, null, function* () {
|
|
925
1010
|
if (!(yield this._initialized)) return;
|
|
@@ -939,7 +1024,7 @@ var IORoom = class {
|
|
|
939
1024
|
}, /* @__PURE__ */ new Map())) != null ? _b : this._sessions;
|
|
940
1025
|
const promises = Array.from(webSockets.values()).map((pluvWs) => __async(this, null, function* () {
|
|
941
1026
|
var _a2;
|
|
942
|
-
const session =
|
|
1027
|
+
const session = pluvWs.session;
|
|
943
1028
|
const user = (_a2 = session.user) != null ? _a2 : null;
|
|
944
1029
|
this._sendMessage(pluvWs, { connectionId, data, room, type, user });
|
|
945
1030
|
}));
|
|
@@ -953,8 +1038,13 @@ var IORoom = class {
|
|
|
953
1038
|
if (typeof senderId !== "string") return;
|
|
954
1039
|
const pluvWs = this._sessions.get(senderId);
|
|
955
1040
|
if (!pluvWs) return;
|
|
956
|
-
if (message.type === "$pong")
|
|
957
|
-
|
|
1041
|
+
if (message.type === "$pong") {
|
|
1042
|
+
const elapsedMs = Date.now() - this._lastGarbageCollectMs;
|
|
1043
|
+
if (elapsedMs > GARBAGE_COLLECT_INTERVAL_MS) {
|
|
1044
|
+
yield this.garbageCollect();
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
const session = pluvWs.session;
|
|
958
1048
|
const user = (_b = session.user) != null ? _b : null;
|
|
959
1049
|
this._sendMessage(pluvWs, __spreadValues({
|
|
960
1050
|
connectionId: senderId,
|
|
@@ -973,9 +1063,19 @@ var IORoom = class {
|
|
|
973
1063
|
const context = {
|
|
974
1064
|
context: this._context,
|
|
975
1065
|
doc,
|
|
1066
|
+
garbageCollect: () => __async(this, null, function* () {
|
|
1067
|
+
yield this.garbageCollect();
|
|
1068
|
+
}),
|
|
1069
|
+
get presence() {
|
|
1070
|
+
return null;
|
|
1071
|
+
},
|
|
1072
|
+
set presence(presence) {
|
|
1073
|
+
return;
|
|
1074
|
+
},
|
|
976
1075
|
room: this.id,
|
|
977
1076
|
session: null,
|
|
978
|
-
sessions:
|
|
1077
|
+
sessions: this._getSessions(),
|
|
1078
|
+
time: (/* @__PURE__ */ new Date()).getTime()
|
|
979
1079
|
};
|
|
980
1080
|
const resolver = (_a = this._getProcedure(message)) == null ? void 0 : _a.config.sync;
|
|
981
1081
|
if (!resolver) return;
|
|
@@ -1005,7 +1105,7 @@ var IORoom = class {
|
|
|
1005
1105
|
};
|
|
1006
1106
|
|
|
1007
1107
|
// src/version.generated.ts
|
|
1008
|
-
var version = "0.
|
|
1108
|
+
var version = "0.41.1";
|
|
1009
1109
|
|
|
1010
1110
|
// src/PluvServer.ts
|
|
1011
1111
|
var PluvServer = class {
|
|
@@ -1021,11 +1121,12 @@ var PluvServer = class {
|
|
|
1021
1121
|
if (currentTime - wsSession.timers.ping > PING_TIMEOUT_MS) return false;
|
|
1022
1122
|
return true;
|
|
1023
1123
|
}).reduce(
|
|
1024
|
-
(acc, { id, presence, user }) => __spreadProps(__spreadValues({}, acc), {
|
|
1124
|
+
(acc, { id, presence, timers, user }) => __spreadProps(__spreadValues({}, acc), {
|
|
1025
1125
|
[id]: {
|
|
1026
1126
|
connectionId: id,
|
|
1027
1127
|
presence,
|
|
1028
1128
|
room,
|
|
1129
|
+
timers: { presence: timers.presence },
|
|
1029
1130
|
user
|
|
1030
1131
|
}
|
|
1031
1132
|
}),
|
|
@@ -1035,13 +1136,15 @@ var PluvServer = class {
|
|
|
1035
1136
|
}),
|
|
1036
1137
|
$initializeSession: this._procedure.broadcast((data, { session }) => {
|
|
1037
1138
|
const presence = data == null ? void 0 : data.presence;
|
|
1139
|
+
const timers = session.timers;
|
|
1038
1140
|
if (!session) return {};
|
|
1039
1141
|
session.presence = presence;
|
|
1040
1142
|
return {
|
|
1041
1143
|
$userJoined: {
|
|
1042
1144
|
connectionId: session.id,
|
|
1043
1145
|
user: session.user,
|
|
1044
|
-
presence
|
|
1146
|
+
presence,
|
|
1147
|
+
timers: { presence: timers.presence }
|
|
1045
1148
|
}
|
|
1046
1149
|
};
|
|
1047
1150
|
}).self((_0, _1) => __async(this, [_0, _1], function* (data, { context, doc, room, session }) {
|
|
@@ -1077,12 +1180,24 @@ var PluvServer = class {
|
|
|
1077
1180
|
}));
|
|
1078
1181
|
return { $pong: {} };
|
|
1079
1182
|
}),
|
|
1080
|
-
$updatePresence: this._procedure.broadcast((data,
|
|
1183
|
+
$updatePresence: this._procedure.broadcast((data, context) => {
|
|
1081
1184
|
const presence = data == null ? void 0 : data.presence;
|
|
1185
|
+
const { session } = context;
|
|
1082
1186
|
if (!session) return {};
|
|
1083
1187
|
const updated = Object.assign(/* @__PURE__ */ Object.create(null), session.presence, presence);
|
|
1084
|
-
|
|
1085
|
-
|
|
1188
|
+
const bytes = new TextEncoder().encode(JSON.stringify(updated)).length;
|
|
1189
|
+
if (bytes > MAX_PRESENCE_SIZE_BYTES) {
|
|
1190
|
+
throw new Error(
|
|
1191
|
+
`Large presence. Presence must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
context.presence = updated;
|
|
1195
|
+
return {
|
|
1196
|
+
$presenceUpdated: {
|
|
1197
|
+
presence: updated,
|
|
1198
|
+
timers: { presence: session.timers.presence }
|
|
1199
|
+
}
|
|
1200
|
+
};
|
|
1086
1201
|
}),
|
|
1087
1202
|
$updateStorage: this._procedure.broadcast((data, { context, doc, room }) => {
|
|
1088
1203
|
var _a;
|
|
@@ -1195,8 +1310,16 @@ var PluvServer = class {
|
|
|
1195
1310
|
if (!this._authorize) {
|
|
1196
1311
|
throw new Error("IO does not specify authorize during initialization.");
|
|
1197
1312
|
}
|
|
1198
|
-
if (this._platform._createToken) return yield this._platform._createToken(params);
|
|
1199
1313
|
const ioAuthorize = this._getIOAuthorize(params);
|
|
1314
|
+
const user = params.user;
|
|
1315
|
+
const parsed = !!ioAuthorize ? ioAuthorize.user.parse(user) : user;
|
|
1316
|
+
const bytes = new TextEncoder().encode(JSON.stringify(parsed)).length;
|
|
1317
|
+
if (bytes > MAX_USER_SIZE_BYTES) {
|
|
1318
|
+
throw new Error(
|
|
1319
|
+
`createToken called with large payload. User must be at most 512 bytes. Current size: ${bytes.toLocaleString()}`
|
|
1320
|
+
);
|
|
1321
|
+
}
|
|
1322
|
+
if (this._platform._createToken) return yield this._platform._createToken(params);
|
|
1200
1323
|
const secret = (_a = ioAuthorize == null ? void 0 : ioAuthorize.secret) != null ? _a : null;
|
|
1201
1324
|
if (!secret) throw new Error("`authorize` was specified without a valid secret");
|
|
1202
1325
|
return yield authorize({ platform: this._platform, secret }).encode(params);
|