@pluv/client 2.0.1 → 2.1.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 +104 -0
- package/dist/index.d.mts +27 -25
- package/dist/index.d.ts +27 -25
- package/dist/index.js +214 -68
- package/dist/index.mjs +214 -68
- package/package.json +6 -6
- package/src/CrdtNotifier.ts +2 -1
- package/src/MockedRoom.ts +83 -33
- package/src/PluvRoom.ts +160 -58
- package/src/StateNotifier.ts +11 -17
- package/src/UsersNotifier.ts +66 -0
- package/src/OtherNotifier.ts +0 -50
package/dist/index.js
CHANGED
|
@@ -228,35 +228,6 @@ var EventNotifier = class {
|
|
|
228
228
|
}
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
-
// src/OtherNotifier.ts
|
|
232
|
-
var import_wonka3 = require("wonka");
|
|
233
|
-
var OtherNotifier = class {
|
|
234
|
-
constructor() {
|
|
235
|
-
this._subjects = /* @__PURE__ */ new Map();
|
|
236
|
-
}
|
|
237
|
-
clear() {
|
|
238
|
-
this._subjects.forEach((subject) => {
|
|
239
|
-
subject.next(null);
|
|
240
|
-
});
|
|
241
|
-
this._subjects.clear();
|
|
242
|
-
}
|
|
243
|
-
delete(clientId) {
|
|
244
|
-
this.subject(clientId).next(null);
|
|
245
|
-
this._subjects.delete(clientId);
|
|
246
|
-
}
|
|
247
|
-
subject(clientId) {
|
|
248
|
-
const subject = this._subjects.get(clientId);
|
|
249
|
-
if (subject) return subject;
|
|
250
|
-
const newSubject = (0, import_wonka3.makeSubject)();
|
|
251
|
-
this._subjects.set(clientId, newSubject);
|
|
252
|
-
return newSubject;
|
|
253
|
-
}
|
|
254
|
-
subscribe(clientId, callback) {
|
|
255
|
-
const source = this.subject(clientId).source;
|
|
256
|
-
return (0, import_wonka3.subscribe)(callback)(source).unsubscribe;
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
|
|
260
231
|
// src/PluvRouter.ts
|
|
261
232
|
var PluvRouter = class _PluvRouter {
|
|
262
233
|
constructor(events) {
|
|
@@ -285,22 +256,22 @@ var PluvRouter = class _PluvRouter {
|
|
|
285
256
|
};
|
|
286
257
|
|
|
287
258
|
// src/StateNotifier.ts
|
|
288
|
-
var
|
|
259
|
+
var import_wonka3 = require("wonka");
|
|
289
260
|
var StateNotifier = class {
|
|
290
261
|
constructor() {
|
|
291
262
|
this.subjects = {
|
|
292
|
-
connection: (0,
|
|
293
|
-
"my-presence": (0,
|
|
294
|
-
myself: (0,
|
|
295
|
-
others: (0,
|
|
296
|
-
"storage-loaded": (0,
|
|
263
|
+
connection: (0, import_wonka3.makeSubject)(),
|
|
264
|
+
"my-presence": (0, import_wonka3.makeSubject)(),
|
|
265
|
+
myself: (0, import_wonka3.makeSubject)(),
|
|
266
|
+
others: (0, import_wonka3.makeSubject)(),
|
|
267
|
+
"storage-loaded": (0, import_wonka3.makeSubject)()
|
|
297
268
|
};
|
|
298
269
|
}
|
|
299
270
|
subscribe(name, callback) {
|
|
300
271
|
var _a;
|
|
301
272
|
const source = (_a = this.subjects[name]) == null ? void 0 : _a.source;
|
|
302
273
|
if (!source) throw new Error(`Could not subscribe to source: ${name}`);
|
|
303
|
-
return (0,
|
|
274
|
+
return (0, import_wonka3.subscribe)(callback)(source).unsubscribe;
|
|
304
275
|
}
|
|
305
276
|
};
|
|
306
277
|
|
|
@@ -550,6 +521,43 @@ var UsersManager = class {
|
|
|
550
521
|
}
|
|
551
522
|
};
|
|
552
523
|
|
|
524
|
+
// src/UsersNotifier.ts
|
|
525
|
+
var import_wonka4 = require("wonka");
|
|
526
|
+
var UsersNotifier = class {
|
|
527
|
+
constructor() {
|
|
528
|
+
this.others = (0, import_wonka4.makeSubject)();
|
|
529
|
+
this._otherSubjects = /* @__PURE__ */ new Map();
|
|
530
|
+
}
|
|
531
|
+
clear() {
|
|
532
|
+
this._otherSubjects.forEach((subject) => {
|
|
533
|
+
subject.next(null);
|
|
534
|
+
});
|
|
535
|
+
this._otherSubjects.clear();
|
|
536
|
+
}
|
|
537
|
+
delete(clientId) {
|
|
538
|
+
this.other(clientId).next(null);
|
|
539
|
+
this._otherSubjects.delete(clientId);
|
|
540
|
+
}
|
|
541
|
+
other(clientId) {
|
|
542
|
+
const subject = this._otherSubjects.get(clientId);
|
|
543
|
+
if (subject) return subject;
|
|
544
|
+
const newSubject = (0, import_wonka4.makeSubject)();
|
|
545
|
+
this._otherSubjects.set(clientId, newSubject);
|
|
546
|
+
return newSubject;
|
|
547
|
+
}
|
|
548
|
+
subscribeOther(clientId, callback) {
|
|
549
|
+
const source = this.other(clientId).source;
|
|
550
|
+
const subscription = (0, import_wonka4.subscribe)(callback)(source);
|
|
551
|
+
return subscription.unsubscribe;
|
|
552
|
+
}
|
|
553
|
+
subscribeOthers(callback) {
|
|
554
|
+
const subscription = (0, import_wonka4.subscribe)(
|
|
555
|
+
({ others, event }) => callback(others, event)
|
|
556
|
+
)(this.others.source);
|
|
557
|
+
return subscription.unsubscribe;
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
|
|
553
561
|
// src/PluvRoom.ts
|
|
554
562
|
var ADD_TO_STORAGE_STATE_DEBOUNCE_MS = 1e3;
|
|
555
563
|
var HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -569,7 +577,6 @@ var PluvRoom = class {
|
|
|
569
577
|
this._intervals = {
|
|
570
578
|
heartbeat: null
|
|
571
579
|
};
|
|
572
|
-
this._otherNotifier = new OtherNotifier();
|
|
573
580
|
this._publicKey = null;
|
|
574
581
|
this._stateNotifier = new StateNotifier();
|
|
575
582
|
this._subscriptions = {
|
|
@@ -579,6 +586,7 @@ var PluvRoom = class {
|
|
|
579
586
|
pong: null,
|
|
580
587
|
reconnect: null
|
|
581
588
|
};
|
|
589
|
+
this._usersNotifier = new UsersNotifier();
|
|
582
590
|
this._lastMetadata = null;
|
|
583
591
|
this._state = {
|
|
584
592
|
authorization: {
|
|
@@ -633,6 +641,9 @@ var PluvRoom = class {
|
|
|
633
641
|
this.canUndo = () => {
|
|
634
642
|
return !!this._crdtManager.doc.canUndo();
|
|
635
643
|
};
|
|
644
|
+
/**
|
|
645
|
+
* @deprecated To be removed in v3. Use PluvRoom.subscribe.event instead
|
|
646
|
+
*/
|
|
636
647
|
this.event = new Proxy(
|
|
637
648
|
(event, callback) => this._eventNotifier.subscribe(event, callback),
|
|
638
649
|
{
|
|
@@ -664,23 +675,77 @@ var PluvRoom = class {
|
|
|
664
675
|
if (typeof sharedType === "undefined") return null;
|
|
665
676
|
return sharedType;
|
|
666
677
|
};
|
|
678
|
+
/**
|
|
679
|
+
* @deprecated To be removed in v3. Use PluvRoom.subscribe.other instead
|
|
680
|
+
*/
|
|
667
681
|
this.other = (connectionId, callback) => {
|
|
668
682
|
const clientId = this._usersManager.getClientId(connectionId);
|
|
669
683
|
if (!clientId) return () => void 0;
|
|
670
|
-
return this.
|
|
684
|
+
return this._usersNotifier.subscribeOther(clientId, callback);
|
|
671
685
|
};
|
|
672
686
|
this.redo = () => {
|
|
673
687
|
this._crdtManager.doc.redo();
|
|
674
688
|
};
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
this.
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
689
|
+
/**
|
|
690
|
+
* @deprecated To be removed in v3. To be removed in v3. Use PluvRoom.subscribe.storage instead
|
|
691
|
+
*/
|
|
692
|
+
this.storage = new Proxy(
|
|
693
|
+
(key, callback) => this._crdtNotifier.subscribe(key, callback),
|
|
694
|
+
{
|
|
695
|
+
get: (fn, prop) => {
|
|
696
|
+
if (!!prop) {
|
|
697
|
+
return (callback) => {
|
|
698
|
+
return this._crdtNotifier.subcribeRoot(callback);
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
return (callback) => {
|
|
702
|
+
return fn(prop, callback);
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
);
|
|
707
|
+
/**
|
|
708
|
+
* @deprecated To be removed in v3. Use PluvRoom.subscribe.storage instead
|
|
709
|
+
* @description Subscribes to the root storage object (serialized)
|
|
710
|
+
*/
|
|
711
|
+
this.storageRoot = (callback) => {
|
|
712
|
+
return this._crdtNotifier.subcribeRoot(callback);
|
|
683
713
|
};
|
|
714
|
+
this.subscribe = new Proxy(
|
|
715
|
+
(name, callback) => this._stateNotifier.subscribe(name, callback),
|
|
716
|
+
{
|
|
717
|
+
get: (fn, prop) => {
|
|
718
|
+
if (prop === "connection") {
|
|
719
|
+
return (callback) => {
|
|
720
|
+
return fn("connection", callback);
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
if (prop === "myPresence") {
|
|
724
|
+
return (callback) => {
|
|
725
|
+
return fn("my-presence", callback);
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
if (prop === "myself") {
|
|
729
|
+
return (callback) => {
|
|
730
|
+
return fn("myself", callback);
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
if (prop === "others") {
|
|
734
|
+
return (callback) => {
|
|
735
|
+
return this._usersNotifier.subscribeOthers(callback);
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
if (prop === "storageLoaded") {
|
|
739
|
+
return (callback) => {
|
|
740
|
+
return fn("storage-loaded", callback);
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
if (prop === "event") return this.event;
|
|
744
|
+
if (prop === "other") return this.other;
|
|
745
|
+
if (prop === "storage") return this.storage;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
);
|
|
684
749
|
this.transact = (fn, origin) => {
|
|
685
750
|
const _origin = origin != null ? origin : this._state.connection.id;
|
|
686
751
|
if (typeof _origin !== "string") return;
|
|
@@ -891,9 +956,10 @@ var PluvRoom = class {
|
|
|
891
956
|
this._detachWindowListeners();
|
|
892
957
|
this._usersManager.removeMyself();
|
|
893
958
|
this._usersManager.clearConnections();
|
|
894
|
-
this.
|
|
959
|
+
this._usersNotifier.clear();
|
|
895
960
|
this._stateNotifier.subjects.myself.next(null);
|
|
896
961
|
this._stateNotifier.subjects.others.next([]);
|
|
962
|
+
this._usersNotifier.others.next({ others: [], event: { kind: "clear" } });
|
|
897
963
|
(_c = this._state.webSocket) == null ? void 0 : _c.close();
|
|
898
964
|
this._detachWsListeners();
|
|
899
965
|
}
|
|
@@ -984,7 +1050,16 @@ var PluvRoom = class {
|
|
|
984
1050
|
const deleted = this._usersManager.deleteConnection(connectionId);
|
|
985
1051
|
const others = this._usersManager.getOthers();
|
|
986
1052
|
this._stateNotifier.subjects.others.next(others);
|
|
987
|
-
if (!
|
|
1053
|
+
if (!deleted) {
|
|
1054
|
+
console.warn("Could not identify exited connection");
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
const { data: user, remaining } = deleted;
|
|
1058
|
+
this._usersNotifier.others.next({
|
|
1059
|
+
others,
|
|
1060
|
+
event: { kind: "leave", user }
|
|
1061
|
+
});
|
|
1062
|
+
if (!remaining && !!clientId) this._usersNotifier.delete(clientId);
|
|
988
1063
|
}
|
|
989
1064
|
_handlePresenceUpdatedMessage(message) {
|
|
990
1065
|
var _a;
|
|
@@ -1003,19 +1078,31 @@ var PluvRoom = class {
|
|
|
1003
1078
|
return;
|
|
1004
1079
|
}
|
|
1005
1080
|
if (!!clientId) {
|
|
1006
|
-
const
|
|
1007
|
-
this.
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1081
|
+
const other2 = this._usersManager.getOther(connectionId);
|
|
1082
|
+
const others2 = this._usersManager.getOthers();
|
|
1083
|
+
this._usersNotifier.other(clientId).next(other2);
|
|
1084
|
+
this._stateNotifier.subjects.others.next(others2);
|
|
1085
|
+
if (!!other2) {
|
|
1086
|
+
this._usersNotifier.others.next({
|
|
1087
|
+
others: others2,
|
|
1088
|
+
event: { kind: "update", user: other2 }
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
return;
|
|
1016
1092
|
}
|
|
1093
|
+
const added = this._usersManager.addConnection({
|
|
1094
|
+
connectionId,
|
|
1095
|
+
presence: data.presence,
|
|
1096
|
+
user: message.user
|
|
1097
|
+
});
|
|
1098
|
+
const other = this._usersManager.getOther(connectionId);
|
|
1017
1099
|
const others = this._usersManager.getOthers();
|
|
1100
|
+
this._usersNotifier.other(added.clientId).next(other);
|
|
1018
1101
|
this._stateNotifier.subjects.others.next(others);
|
|
1102
|
+
this._usersNotifier.others.next({
|
|
1103
|
+
others,
|
|
1104
|
+
event: { kind: "update", user: added.data }
|
|
1105
|
+
});
|
|
1019
1106
|
}
|
|
1020
1107
|
_handleReceiveOthers(message) {
|
|
1021
1108
|
if (!message.connectionId) return;
|
|
@@ -1032,10 +1119,14 @@ var PluvRoom = class {
|
|
|
1032
1119
|
if (result.isMyself) return;
|
|
1033
1120
|
const clientId = result.clientId;
|
|
1034
1121
|
const other = this._usersManager.getOther(connectionId);
|
|
1035
|
-
this.
|
|
1122
|
+
this._usersNotifier.other(clientId).next(other);
|
|
1036
1123
|
});
|
|
1037
1124
|
const others = this._usersManager.getOthers();
|
|
1038
1125
|
this._stateNotifier.subjects.others.next(others);
|
|
1126
|
+
this._usersNotifier.others.next({
|
|
1127
|
+
others,
|
|
1128
|
+
event: { kind: "sync", users: others }
|
|
1129
|
+
});
|
|
1039
1130
|
}
|
|
1040
1131
|
_handleRegisteredMessage(message) {
|
|
1041
1132
|
return __async(this, null, function* () {
|
|
@@ -1137,6 +1228,11 @@ var PluvRoom = class {
|
|
|
1137
1228
|
const quitters = this._usersManager.getOthers().filter((other) => !active.has(other.connectionId));
|
|
1138
1229
|
quitters.forEach((quitter) => {
|
|
1139
1230
|
this._usersManager.deleteConnection(quitter.connectionId);
|
|
1231
|
+
const remaining2 = this._usersManager.getOthers();
|
|
1232
|
+
this._usersNotifier.others.next({
|
|
1233
|
+
others: remaining2,
|
|
1234
|
+
event: { kind: "leave", user: quitter }
|
|
1235
|
+
});
|
|
1140
1236
|
});
|
|
1141
1237
|
const remaining = this._usersManager.getOthers();
|
|
1142
1238
|
this._stateNotifier.subjects.others.next(remaining);
|
|
@@ -1159,8 +1255,12 @@ var PluvRoom = class {
|
|
|
1159
1255
|
});
|
|
1160
1256
|
const other = this._usersManager.getOther(connectionId);
|
|
1161
1257
|
const others = this._usersManager.getOthers();
|
|
1162
|
-
this.
|
|
1258
|
+
this._usersNotifier.other(added.clientId).next(other);
|
|
1163
1259
|
this._stateNotifier.subjects.others.next(others);
|
|
1260
|
+
this._usersNotifier.others.next({
|
|
1261
|
+
others,
|
|
1262
|
+
event: { kind: "enter", user: added.data }
|
|
1263
|
+
});
|
|
1164
1264
|
}
|
|
1165
1265
|
_heartbeat() {
|
|
1166
1266
|
this._clearTimeout(this._timeouts.pong);
|
|
@@ -1535,7 +1635,7 @@ var MockedRoom = class {
|
|
|
1535
1635
|
constructor(room, options) {
|
|
1536
1636
|
this._crdtNotifier = new CrdtNotifier();
|
|
1537
1637
|
this._eventNotifier = new EventNotifier();
|
|
1538
|
-
this.
|
|
1638
|
+
this._usersNotifier = new UsersNotifier();
|
|
1539
1639
|
this._state = {
|
|
1540
1640
|
authorization: {
|
|
1541
1641
|
token: null,
|
|
@@ -1622,20 +1722,66 @@ var MockedRoom = class {
|
|
|
1622
1722
|
this.other = (connectionId, callback) => {
|
|
1623
1723
|
const clientId = this._usersManager.getClientId(connectionId);
|
|
1624
1724
|
if (!clientId) return () => void 0;
|
|
1625
|
-
return this.
|
|
1725
|
+
return this._usersNotifier.subscribeOther(clientId, callback);
|
|
1626
1726
|
};
|
|
1627
1727
|
this.redo = () => {
|
|
1628
1728
|
this._crdtManager.doc.redo();
|
|
1629
1729
|
};
|
|
1630
|
-
this.storage = (
|
|
1631
|
-
|
|
1632
|
-
|
|
1730
|
+
this.storage = new Proxy(
|
|
1731
|
+
(key, callback) => this._crdtNotifier.subscribe(key, callback),
|
|
1732
|
+
{
|
|
1733
|
+
get: (fn, prop) => {
|
|
1734
|
+
if (!!prop) {
|
|
1735
|
+
return (callback) => {
|
|
1736
|
+
return this._crdtNotifier.subcribeRoot(callback);
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
return (callback) => {
|
|
1740
|
+
return fn(prop, callback);
|
|
1741
|
+
};
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
);
|
|
1633
1745
|
this.storageRoot = (fn) => {
|
|
1634
1746
|
return this._crdtNotifier.subcribeRoot(fn);
|
|
1635
1747
|
};
|
|
1636
|
-
this.subscribe = (
|
|
1637
|
-
|
|
1638
|
-
|
|
1748
|
+
this.subscribe = new Proxy(
|
|
1749
|
+
(name, callback) => {
|
|
1750
|
+
return this._stateNotifier.subscribe(name, callback);
|
|
1751
|
+
},
|
|
1752
|
+
{
|
|
1753
|
+
get: (fn, prop) => {
|
|
1754
|
+
if (prop === "connection") {
|
|
1755
|
+
return (callback) => {
|
|
1756
|
+
return fn("connection", callback);
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
if (prop === "myPresence") {
|
|
1760
|
+
return (callback) => {
|
|
1761
|
+
return fn("my-presence", callback);
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
if (prop === "myself") {
|
|
1765
|
+
return (callback) => {
|
|
1766
|
+
return fn("myself", callback);
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1769
|
+
if (prop === "others") {
|
|
1770
|
+
return (callback) => {
|
|
1771
|
+
return this._usersNotifier.subscribeOthers(callback);
|
|
1772
|
+
};
|
|
1773
|
+
}
|
|
1774
|
+
if (prop === "storageLoaded") {
|
|
1775
|
+
return (callback) => {
|
|
1776
|
+
return fn("storage-loaded", callback);
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
if (prop === "event") return this.event;
|
|
1780
|
+
if (prop === "other") return this.other;
|
|
1781
|
+
if (prop === "storage") return this.storage;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
);
|
|
1639
1785
|
this.transact = (fn, origin) => {
|
|
1640
1786
|
const _origin = origin != null ? origin : this._state.connection.id;
|
|
1641
1787
|
const crdtManager = this._crdtManager;
|