@pluv/client 2.0.2 → 2.2.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/dist/index.mjs CHANGED
@@ -50,6 +50,7 @@ var AbstractStorageStore = class {
50
50
 
51
51
  // src/constants.ts
52
52
  var MAX_PRESENCE_SIZE_BYTES = 512;
53
+ var PLUV_PRESENCE_META_KEY = "__pluv";
53
54
 
54
55
  // src/PluvProcedure.ts
55
56
  var PluvProcedure = class _PluvProcedure {
@@ -87,7 +88,7 @@ var PluvProcedure = class _PluvProcedure {
87
88
  };
88
89
 
89
90
  // src/PluvRoom.ts
90
- import { ConnectionState } from "@pluv/types";
91
+ import { ConnectionState, StorageState } from "@pluv/types";
91
92
 
92
93
  // src/CrdtManager.ts
93
94
  import { noop } from "@pluv/crdt";
@@ -96,7 +97,7 @@ var CrdtManager = class {
96
97
  this.initialized = false;
97
98
  const { initialStorage = noop.doc({}) } = options;
98
99
  this._docFactory = initialStorage;
99
- this.doc = initialStorage.getEmpty();
100
+ this.doc = this._docFactory.getEmpty();
100
101
  }
101
102
  /**
102
103
  * !HACK
@@ -136,11 +137,7 @@ var CrdtManager = class {
136
137
  if (!updates.length) return this;
137
138
  const initialized = this._docFactory.getInitialized();
138
139
  const reference = initialized.get();
139
- this.doc = this._applyDocUpdates(
140
- this._docFactory.getEmpty(),
141
- updates,
142
- origin
143
- ).rebuildStorage(reference);
140
+ this.doc = this._applyDocUpdates(this.doc, updates, origin).rebuildStorage(reference);
144
141
  this.initialized = true;
145
142
  initialized.destroy();
146
143
  return this;
@@ -200,31 +197,21 @@ var EventNotifier = class {
200
197
  }
201
198
  };
202
199
 
203
- // src/OtherNotifier.ts
200
+ // src/ListenerManager.ts
204
201
  import { makeSubject as makeSubject3, subscribe as subscribe3 } from "wonka";
205
- var OtherNotifier = class {
202
+ var ListenerManager = class {
206
203
  constructor() {
207
- this._subjects = /* @__PURE__ */ new Map();
208
- }
209
- clear() {
210
- this._subjects.forEach((subject) => {
211
- subject.next(null);
212
- });
213
- this._subjects.clear();
214
- }
215
- delete(clientId) {
216
- this.subject(clientId).next(null);
217
- this._subjects.delete(clientId);
218
- }
219
- subject(clientId) {
220
- const subject = this._subjects.get(clientId);
221
- if (subject) return subject;
222
- const newSubject = makeSubject3();
223
- this._subjects.set(clientId, newSubject);
224
- return newSubject;
204
+ this.subjects = {
205
+ close: makeSubject3(),
206
+ error: makeSubject3(),
207
+ message: makeSubject3(),
208
+ open: makeSubject3()
209
+ };
225
210
  }
226
- subscribe(clientId, callback) {
227
- const source = this.subject(clientId).source;
211
+ subscribe(kind, callback) {
212
+ var _a;
213
+ const source = (_a = this.subjects[kind]) == null ? void 0 : _a.source;
214
+ if (!source) return () => void 0;
228
215
  return subscribe3(callback)(source).unsubscribe;
229
216
  }
230
217
  };
@@ -445,6 +432,9 @@ var UsersManager = class {
445
432
  );
446
433
  const presence = __spreadValues(__spreadValues(__spreadValues({}, this.initialPresence), cleanedPresence), cleanedPatch);
447
434
  const validated = this._presence ? this._presence.parse(presence) : presence;
435
+ if (!!presence[PLUV_PRESENCE_META_KEY]) {
436
+ validated[PLUV_PRESENCE_META_KEY] = presence[PLUV_PRESENCE_META_KEY];
437
+ }
448
438
  this._others.set(clientId, __spreadProps(__spreadValues({}, other), { presence: validated }));
449
439
  return validated;
450
440
  }
@@ -522,6 +512,43 @@ var UsersManager = class {
522
512
  }
523
513
  };
524
514
 
515
+ // src/UsersNotifier.ts
516
+ import { makeSubject as makeSubject5, subscribe as subscribe5 } from "wonka";
517
+ var UsersNotifier = class {
518
+ constructor() {
519
+ this.others = makeSubject5();
520
+ this._otherSubjects = /* @__PURE__ */ new Map();
521
+ }
522
+ clear() {
523
+ this._otherSubjects.forEach((subject) => {
524
+ subject.next(null);
525
+ });
526
+ this._otherSubjects.clear();
527
+ }
528
+ delete(clientId) {
529
+ this.other(clientId).next(null);
530
+ this._otherSubjects.delete(clientId);
531
+ }
532
+ other(clientId) {
533
+ const subject = this._otherSubjects.get(clientId);
534
+ if (subject) return subject;
535
+ const newSubject = makeSubject5();
536
+ this._otherSubjects.set(clientId, newSubject);
537
+ return newSubject;
538
+ }
539
+ subscribeOther(clientId, callback) {
540
+ const source = this.other(clientId).source;
541
+ const subscription = subscribe5(callback)(source);
542
+ return subscription.unsubscribe;
543
+ }
544
+ subscribeOthers(callback) {
545
+ const subscription = subscribe5(
546
+ ({ others, event }) => callback(others, event)
547
+ )(this.others.source);
548
+ return subscription.unsubscribe;
549
+ }
550
+ };
551
+
525
552
  // src/PluvRoom.ts
526
553
  var ADD_TO_STORAGE_STATE_DEBOUNCE_MS = 1e3;
527
554
  var HEARTBEAT_INTERVAL_MS = 1e4;
@@ -541,7 +568,7 @@ var PluvRoom = class {
541
568
  this._intervals = {
542
569
  heartbeat: null
543
570
  };
544
- this._otherNotifier = new OtherNotifier();
571
+ this._listenerManager = new ListenerManager();
545
572
  this._publicKey = null;
546
573
  this._stateNotifier = new StateNotifier();
547
574
  this._subscriptions = {
@@ -551,6 +578,7 @@ var PluvRoom = class {
551
578
  pong: null,
552
579
  reconnect: null
553
580
  };
581
+ this._usersNotifier = new UsersNotifier();
554
582
  this._lastMetadata = null;
555
583
  this._state = {
556
584
  authorization: {
@@ -559,10 +587,12 @@ var PluvRoom = class {
559
587
  },
560
588
  connection: {
561
589
  attempts: 0,
562
- count: 0,
563
590
  id: null,
564
591
  state: ConnectionState.Untouched
565
592
  },
593
+ storage: {
594
+ state: StorageState.Unavailable
595
+ },
566
596
  webSocket: null
567
597
  };
568
598
  this._windowListeners = null;
@@ -605,6 +635,9 @@ var PluvRoom = class {
605
635
  this.canUndo = () => {
606
636
  return !!this._crdtManager.doc.canUndo();
607
637
  };
638
+ /**
639
+ * @deprecated To be removed in v3. Use PluvRoom.subscribe.event instead
640
+ */
608
641
  this.event = new Proxy(
609
642
  (event, callback) => this._eventNotifier.subscribe(event, callback),
610
643
  {
@@ -636,23 +669,80 @@ var PluvRoom = class {
636
669
  if (typeof sharedType === "undefined") return null;
637
670
  return sharedType;
638
671
  };
672
+ this.getStorageLoaded = () => {
673
+ return this._state.storage.state === StorageState.Offline || this._state.storage.state === StorageState.Synced;
674
+ };
675
+ /**
676
+ * @deprecated To be removed in v3. Use PluvRoom.subscribe.other instead
677
+ */
639
678
  this.other = (connectionId, callback) => {
640
679
  const clientId = this._usersManager.getClientId(connectionId);
641
680
  if (!clientId) return () => void 0;
642
- return this._otherNotifier.subscribe(clientId, callback);
681
+ return this._usersNotifier.subscribeOther(clientId, callback);
643
682
  };
644
683
  this.redo = () => {
645
684
  this._crdtManager.doc.redo();
646
685
  };
647
- this.storage = (key, fn) => {
648
- return this._crdtNotifier.subscribe(key, fn);
649
- };
650
- this.storageRoot = (fn) => {
651
- return this._crdtNotifier.subcribeRoot(fn);
652
- };
653
- this.subscribe = (name, callback) => {
654
- return this._stateNotifier.subscribe(name, callback);
686
+ /**
687
+ * @deprecated To be removed in v3. Use PluvRoom.subscribe.storage instead
688
+ */
689
+ this.storage = new Proxy(
690
+ (key, callback) => this._crdtNotifier.subscribe(key, callback),
691
+ {
692
+ get: (fn, prop) => {
693
+ if (!!prop) {
694
+ return (callback) => {
695
+ return this._crdtNotifier.subcribeRoot(callback);
696
+ };
697
+ }
698
+ return (callback) => {
699
+ return fn(prop, callback);
700
+ };
701
+ }
702
+ }
703
+ );
704
+ /**
705
+ * @deprecated To be removed in v3. Use PluvRoom.subscribe.storage instead
706
+ * @description Subscribes to the root storage object (serialized)
707
+ */
708
+ this.storageRoot = (callback) => {
709
+ return this._crdtNotifier.subcribeRoot(callback);
655
710
  };
711
+ this.subscribe = new Proxy(
712
+ (name, callback) => this._stateNotifier.subscribe(name, callback),
713
+ {
714
+ get: (fn, prop) => {
715
+ if (prop === "connection") {
716
+ return (callback) => {
717
+ return fn("connection", callback);
718
+ };
719
+ }
720
+ if (prop === "myPresence") {
721
+ return (callback) => {
722
+ return fn("my-presence", callback);
723
+ };
724
+ }
725
+ if (prop === "myself") {
726
+ return (callback) => {
727
+ return fn("myself", callback);
728
+ };
729
+ }
730
+ if (prop === "others") {
731
+ return (callback) => {
732
+ return this._usersNotifier.subscribeOthers(callback);
733
+ };
734
+ }
735
+ if (prop === "storageLoaded") {
736
+ return (callback) => {
737
+ return fn("storage-loaded", callback);
738
+ };
739
+ }
740
+ if (prop === "event") return this.event;
741
+ if (prop === "other") return this.other;
742
+ if (prop === "storage") return this.storage;
743
+ }
744
+ }
745
+ );
656
746
  this.transact = (fn, origin) => {
657
747
  const _origin = origin != null ? origin : this._state.connection.id;
658
748
  if (typeof _origin !== "string") return;
@@ -732,12 +822,18 @@ var PluvRoom = class {
732
822
  });
733
823
  this._crdtManager = new CrdtManager({ initialStorage });
734
824
  }
825
+ /**
826
+ * @deprecated To be removed in v3. Use `getStorageLoaded` instead.
827
+ */
735
828
  get storageLoaded() {
736
- return this._crdtManager.initialized;
829
+ return this.getStorageLoaded();
737
830
  }
738
831
  get webSocket() {
739
832
  return this._state.webSocket;
740
833
  }
834
+ addEventListener(kind, handler) {
835
+ return this._listenerManager.subscribe(kind, handler);
836
+ }
741
837
  connect(...args) {
742
838
  return __async(this, null, function* () {
743
839
  var _a;
@@ -779,6 +875,7 @@ var PluvRoom = class {
779
875
  this._updateState((oldState) => {
780
876
  oldState.connection.attempts = 0;
781
877
  oldState.authorization.token = authToken;
878
+ oldState.storage.state = StorageState.Loading;
782
879
  oldState.webSocket = webSocket;
783
880
  return oldState;
784
881
  });
@@ -799,6 +896,7 @@ var PluvRoom = class {
799
896
  this._updateState((oldState) => {
800
897
  oldState.authorization.token = null;
801
898
  oldState.connection.state = ConnectionState.Closed;
899
+ oldState.storage.state = oldState.storage.state === StorageState.Synced ? StorageState.Offline : StorageState.Unavailable;
802
900
  oldState.webSocket = null;
803
901
  return oldState;
804
902
  });
@@ -863,9 +961,10 @@ var PluvRoom = class {
863
961
  this._detachWindowListeners();
864
962
  this._usersManager.removeMyself();
865
963
  this._usersManager.clearConnections();
866
- this._otherNotifier.clear();
964
+ this._usersNotifier.clear();
867
965
  this._stateNotifier.subjects.myself.next(null);
868
966
  this._stateNotifier.subjects.others.next([]);
967
+ this._usersNotifier.others.next({ others: [], event: { kind: "clear" } });
869
968
  (_c = this._state.webSocket) == null ? void 0 : _c.close();
870
969
  this._detachWsListeners();
871
970
  }
@@ -956,7 +1055,16 @@ var PluvRoom = class {
956
1055
  const deleted = this._usersManager.deleteConnection(connectionId);
957
1056
  const others = this._usersManager.getOthers();
958
1057
  this._stateNotifier.subjects.others.next(others);
959
- if (!(deleted == null ? void 0 : deleted.remaining) && !!clientId) this._otherNotifier.delete(clientId);
1058
+ if (!deleted) {
1059
+ console.warn("Could not identify exited connection");
1060
+ return;
1061
+ }
1062
+ const { data: user, remaining } = deleted;
1063
+ this._usersNotifier.others.next({
1064
+ others,
1065
+ event: { kind: "leave", user }
1066
+ });
1067
+ if (!remaining && !!clientId) this._usersNotifier.delete(clientId);
960
1068
  }
961
1069
  _handlePresenceUpdatedMessage(message) {
962
1070
  var _a;
@@ -975,19 +1083,31 @@ var PluvRoom = class {
975
1083
  return;
976
1084
  }
977
1085
  if (!!clientId) {
978
- const other = this._usersManager.getOther(connectionId);
979
- this._otherNotifier.subject(clientId).next(other);
980
- } else {
981
- const added = this._usersManager.addConnection({
982
- connectionId,
983
- presence: data.presence,
984
- user: message.user
985
- });
986
- const other = this._usersManager.getOther(connectionId);
987
- this._otherNotifier.subject(added.clientId).next(other);
1086
+ const other2 = this._usersManager.getOther(connectionId);
1087
+ const others2 = this._usersManager.getOthers();
1088
+ this._usersNotifier.other(clientId).next(other2);
1089
+ this._stateNotifier.subjects.others.next(others2);
1090
+ if (!!other2) {
1091
+ this._usersNotifier.others.next({
1092
+ others: others2,
1093
+ event: { kind: "update", user: other2 }
1094
+ });
1095
+ }
1096
+ return;
988
1097
  }
1098
+ const added = this._usersManager.addConnection({
1099
+ connectionId,
1100
+ presence: data.presence,
1101
+ user: message.user
1102
+ });
1103
+ const other = this._usersManager.getOther(connectionId);
989
1104
  const others = this._usersManager.getOthers();
1105
+ this._usersNotifier.other(added.clientId).next(other);
990
1106
  this._stateNotifier.subjects.others.next(others);
1107
+ this._usersNotifier.others.next({
1108
+ others,
1109
+ event: { kind: "update", user: added.data }
1110
+ });
991
1111
  }
992
1112
  _handleReceiveOthers(message) {
993
1113
  if (!message.connectionId) return;
@@ -1004,10 +1124,14 @@ var PluvRoom = class {
1004
1124
  if (result.isMyself) return;
1005
1125
  const clientId = result.clientId;
1006
1126
  const other = this._usersManager.getOther(connectionId);
1007
- this._otherNotifier.subject(clientId).next(other);
1127
+ this._usersNotifier.other(clientId).next(other);
1008
1128
  });
1009
1129
  const others = this._usersManager.getOthers();
1010
1130
  this._stateNotifier.subjects.others.next(others);
1131
+ this._usersNotifier.others.next({
1132
+ others,
1133
+ event: { kind: "sync", users: others }
1134
+ });
1011
1135
  }
1012
1136
  _handleRegisteredMessage(message) {
1013
1137
  return __async(this, null, function* () {
@@ -1019,7 +1143,6 @@ var PluvRoom = class {
1019
1143
  const data = message.data;
1020
1144
  const state = data.state;
1021
1145
  this._updateState((oldState) => {
1022
- oldState.connection.count += 1;
1023
1146
  oldState.connection.id = connectionId;
1024
1147
  oldState.authorization.user = user != null ? user : null;
1025
1148
  return oldState;
@@ -1071,6 +1194,10 @@ var PluvRoom = class {
1071
1194
  const encodedState = this._crdtManager.doc.getEncodedState();
1072
1195
  this._emitSharedTypes();
1073
1196
  this._observeCrdt();
1197
+ this._updateState((oldState) => {
1198
+ oldState.storage.state = StorageState.Synced;
1199
+ return oldState;
1200
+ });
1074
1201
  this._stateNotifier.subjects["storage-loaded"].next(true);
1075
1202
  this._sendMessage({
1076
1203
  type: "$updateStorage",
@@ -1109,6 +1236,11 @@ var PluvRoom = class {
1109
1236
  const quitters = this._usersManager.getOthers().filter((other) => !active.has(other.connectionId));
1110
1237
  quitters.forEach((quitter) => {
1111
1238
  this._usersManager.deleteConnection(quitter.connectionId);
1239
+ const remaining2 = this._usersManager.getOthers();
1240
+ this._usersNotifier.others.next({
1241
+ others: remaining2,
1242
+ event: { kind: "leave", user: quitter }
1243
+ });
1112
1244
  });
1113
1245
  const remaining = this._usersManager.getOthers();
1114
1246
  this._stateNotifier.subjects.others.next(remaining);
@@ -1131,8 +1263,12 @@ var PluvRoom = class {
1131
1263
  });
1132
1264
  const other = this._usersManager.getOther(connectionId);
1133
1265
  const others = this._usersManager.getOthers();
1134
- this._otherNotifier.subject(added.clientId).next(other);
1266
+ this._usersNotifier.other(added.clientId).next(other);
1135
1267
  this._stateNotifier.subjects.others.next(others);
1268
+ this._usersNotifier.others.next({
1269
+ others,
1270
+ event: { kind: "enter", user: added.data }
1271
+ });
1136
1272
  }
1137
1273
  _heartbeat() {
1138
1274
  this._clearTimeout(this._timeouts.pong);
@@ -1174,11 +1310,13 @@ var PluvRoom = class {
1174
1310
  this._listeners.onAuthorizationFail(authError);
1175
1311
  this._updateState((oldState) => {
1176
1312
  oldState.connection.state = ConnectionState.Unavailable;
1313
+ oldState.storage.state = StorageState.Unavailable;
1177
1314
  return oldState;
1178
1315
  });
1179
1316
  }
1180
1317
  _onClose(event) {
1181
1318
  return __async(this, null, function* () {
1319
+ this._listenerManager.subjects.close.next(event);
1182
1320
  this._logDebug("WebSocket closed");
1183
1321
  if (!!event.reason) this._logDebug(event.reason);
1184
1322
  const shouldRetry = [
@@ -1206,6 +1344,7 @@ var PluvRoom = class {
1206
1344
  */
1207
1345
  ConnectionState.Closed
1208
1346
  );
1347
+ oldState.storage.state = oldState.storage.state === StorageState.Synced ? StorageState.Offline : StorageState.Unavailable;
1209
1348
  oldState.webSocket = null;
1210
1349
  return oldState;
1211
1350
  });
@@ -1222,9 +1361,11 @@ var PluvRoom = class {
1222
1361
  * @description Handle websocket errors in a meaningful way, should they occur
1223
1362
  * @date August 19, 2022
1224
1363
  */
1225
- _onError() {
1364
+ _onError(event) {
1365
+ this._listenerManager.subjects.error.next(event);
1226
1366
  }
1227
1367
  _onMessage(event) {
1368
+ this._listenerManager.subjects.message.next(event);
1228
1369
  const message = this._parseMessage(event);
1229
1370
  if (!message) return;
1230
1371
  const shouldLog = typeof this._debug === "boolean" ? this._debug : this._debug.output.find((value) => value === message.type);
@@ -1272,7 +1413,8 @@ var PluvRoom = class {
1272
1413
  default:
1273
1414
  }
1274
1415
  }
1275
- _onOpen() {
1416
+ _onOpen(event) {
1417
+ this._listenerManager.subjects.open.next(event);
1276
1418
  if (this._state.connection.state !== ConnectionState.Connecting) return;
1277
1419
  this._logDebug("WebSocket connected");
1278
1420
  this._updateState((oldState) => {
@@ -1290,6 +1432,7 @@ var PluvRoom = class {
1290
1432
  if (this._state.connection.state === ConnectionState.Closed) return;
1291
1433
  this._updateState((oldState) => {
1292
1434
  oldState.connection.state = ConnectionState.Unavailable;
1435
+ oldState.storage.state = oldState.storage.state === StorageState.Synced ? StorageState.Offline : StorageState.Unavailable;
1293
1436
  return oldState;
1294
1437
  });
1295
1438
  });
@@ -1389,6 +1532,7 @@ var PluvRoom = class {
1389
1532
  const oldState = __spreadProps(__spreadValues({}, this._state), {
1390
1533
  authorization,
1391
1534
  connection: JSON.parse(JSON.stringify(this._state.connection)),
1535
+ storage: JSON.parse(JSON.stringify(this._state.storage)),
1392
1536
  webSocket: this._state.webSocket
1393
1537
  });
1394
1538
  const newState = updater(oldState);
@@ -1502,12 +1646,16 @@ var createClient = (options) => {
1502
1646
  var infer = (callback) => callback;
1503
1647
 
1504
1648
  // src/MockedRoom.ts
1505
- import { ConnectionState as ConnectionState2 } from "@pluv/types";
1649
+ import { ConnectionState as ConnectionState2, StorageState as StorageState2 } from "@pluv/types";
1506
1650
  var MockedRoom = class {
1507
1651
  constructor(room, options) {
1652
+ /**
1653
+ * @deprecated To be removed in v3. Use `getStorageLoaded` instead.
1654
+ */
1655
+ this.storageLoaded = true;
1508
1656
  this._crdtNotifier = new CrdtNotifier();
1509
1657
  this._eventNotifier = new EventNotifier();
1510
- this._otherNotifier = new OtherNotifier();
1658
+ this._usersNotifier = new UsersNotifier();
1511
1659
  this._state = {
1512
1660
  authorization: {
1513
1661
  token: null,
@@ -1515,10 +1663,12 @@ var MockedRoom = class {
1515
1663
  },
1516
1664
  connection: {
1517
1665
  attempts: 0,
1518
- count: 1,
1519
1666
  id: null,
1520
1667
  state: ConnectionState2.Untouched
1521
1668
  },
1669
+ storage: {
1670
+ state: StorageState2.Unavailable
1671
+ },
1522
1672
  webSocket: null
1523
1673
  };
1524
1674
  this._stateNotifier = new StateNotifier();
@@ -1594,20 +1744,66 @@ var MockedRoom = class {
1594
1744
  this.other = (connectionId, callback) => {
1595
1745
  const clientId = this._usersManager.getClientId(connectionId);
1596
1746
  if (!clientId) return () => void 0;
1597
- return this._otherNotifier.subscribe(clientId, callback);
1747
+ return this._usersNotifier.subscribeOther(clientId, callback);
1598
1748
  };
1599
1749
  this.redo = () => {
1600
1750
  this._crdtManager.doc.redo();
1601
1751
  };
1602
- this.storage = (key, fn) => {
1603
- return this._crdtNotifier.subscribe(key, fn);
1604
- };
1752
+ this.storage = new Proxy(
1753
+ (key, callback) => this._crdtNotifier.subscribe(key, callback),
1754
+ {
1755
+ get: (fn, prop) => {
1756
+ if (!!prop) {
1757
+ return (callback) => {
1758
+ return this._crdtNotifier.subcribeRoot(callback);
1759
+ };
1760
+ }
1761
+ return (callback) => {
1762
+ return fn(prop, callback);
1763
+ };
1764
+ }
1765
+ }
1766
+ );
1605
1767
  this.storageRoot = (fn) => {
1606
1768
  return this._crdtNotifier.subcribeRoot(fn);
1607
1769
  };
1608
- this.subscribe = (name, callback) => {
1609
- return this._stateNotifier.subscribe(name, callback);
1610
- };
1770
+ this.subscribe = new Proxy(
1771
+ (name, callback) => {
1772
+ return this._stateNotifier.subscribe(name, callback);
1773
+ },
1774
+ {
1775
+ get: (fn, prop) => {
1776
+ if (prop === "connection") {
1777
+ return (callback) => {
1778
+ return fn("connection", callback);
1779
+ };
1780
+ }
1781
+ if (prop === "myPresence") {
1782
+ return (callback) => {
1783
+ return fn("my-presence", callback);
1784
+ };
1785
+ }
1786
+ if (prop === "myself") {
1787
+ return (callback) => {
1788
+ return fn("myself", callback);
1789
+ };
1790
+ }
1791
+ if (prop === "others") {
1792
+ return (callback) => {
1793
+ return this._usersNotifier.subscribeOthers(callback);
1794
+ };
1795
+ }
1796
+ if (prop === "storageLoaded") {
1797
+ return (callback) => {
1798
+ return fn("storage-loaded", callback);
1799
+ };
1800
+ }
1801
+ if (prop === "event") return this.event;
1802
+ if (prop === "other") return this.other;
1803
+ if (prop === "storage") return this.storage;
1804
+ }
1805
+ }
1806
+ );
1611
1807
  this.transact = (fn, origin) => {
1612
1808
  const _origin = origin != null ? origin : this._state.connection.id;
1613
1809
  const crdtManager = this._crdtManager;
@@ -1647,8 +1843,8 @@ var MockedRoom = class {
1647
1843
  });
1648
1844
  this._observeCrdt();
1649
1845
  }
1650
- get storageLoaded() {
1651
- return true;
1846
+ addEventListener(kind, handler) {
1847
+ return () => void 0;
1652
1848
  }
1653
1849
  getDoc() {
1654
1850
  return this._crdtManager.doc;
@@ -1658,6 +1854,9 @@ var MockedRoom = class {
1658
1854
  if (typeof type === "undefined") return this._crdtManager.doc.toJson();
1659
1855
  return this._crdtManager.doc.toJson(type);
1660
1856
  }
1857
+ getStorageLoaded() {
1858
+ return true;
1859
+ }
1661
1860
  _observeCrdt() {
1662
1861
  var _a, _b;
1663
1862
  (_b = (_a = this._subscriptions).observeCrdt) == null ? void 0 : _b.call(_a);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/client",
3
- "version": "2.0.2",
3
+ "version": "2.2.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": "^2.0.2",
22
- "@pluv/types": "^2.0.2"
21
+ "@pluv/crdt": "^2.2.0",
22
+ "@pluv/types": "^2.2.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "eslint": "^9.26.0",
26
26
  "tsup": "^8.4.0",
27
27
  "typescript": "^5.8.3",
28
- "@pluv/tsconfig": "^2.0.2",
29
- "eslint-config-pluv": "^2.0.2"
28
+ "@pluv/tsconfig": "^2.2.0",
29
+ "eslint-config-pluv": "^2.2.0"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsup src/index.ts --format esm,cjs --dts",