@pluv/client 0.11.1 → 0.12.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 +246 -0
- package/dist/index.d.mts +28 -5
- package/dist/index.d.ts +28 -5
- package/dist/index.js +141 -27
- package/dist/index.mjs +141 -27
- package/package.json +7 -7
- package/src/AbstractRoom.ts +28 -9
- package/src/AbstractStorageStore.ts +0 -2
- package/src/CrdtManager.ts +33 -10
- package/src/CrdtNotifier.ts +14 -2
- package/src/EventNotifier.ts +3 -3
- package/src/MockedRoom.ts +76 -19
- package/src/OtherNotifier.ts +3 -3
- package/src/PluvClient.ts +6 -6
- package/src/PluvRoom.ts +111 -22
- package/src/StateNotifier.ts +6 -6
- package/src/UsersManager.ts +4 -4
- package/src/createClient.ts +1 -1
- package/src/index.ts +4 -1
- package/src/types.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -87,14 +87,21 @@ var import_crdt_yjs = require("@pluv/crdt-yjs");
|
|
|
87
87
|
var CrdtManager = class {
|
|
88
88
|
constructor(options = {}) {
|
|
89
89
|
this.initialized = false;
|
|
90
|
-
const {
|
|
90
|
+
const {
|
|
91
|
+
captureTimeout,
|
|
92
|
+
encodedState,
|
|
93
|
+
initialStorage,
|
|
94
|
+
trackedOrigins = []
|
|
95
|
+
} = options;
|
|
91
96
|
const _doc = encodedState ? (0, import_crdt_yjs.doc)().applyUpdate(encodedState) : null;
|
|
92
97
|
if (_doc && !!Object.keys(_doc.toJSON()).length) {
|
|
93
98
|
this.doc = _doc;
|
|
99
|
+
this.trackOrigins({ captureTimeout, trackedOrigins });
|
|
94
100
|
return;
|
|
95
101
|
}
|
|
96
102
|
_doc == null ? void 0 : _doc.destroy();
|
|
97
103
|
this.doc = (0, import_crdt_yjs.doc)(initialStorage == null ? void 0 : initialStorage());
|
|
104
|
+
this.trackOrigins({ captureTimeout, trackedOrigins });
|
|
98
105
|
}
|
|
99
106
|
/**
|
|
100
107
|
* !HACK
|
|
@@ -116,8 +123,15 @@ var CrdtManager = class {
|
|
|
116
123
|
return this.doc.get(key);
|
|
117
124
|
}
|
|
118
125
|
initialize(params) {
|
|
119
|
-
const {
|
|
126
|
+
const {
|
|
127
|
+
captureTimeout,
|
|
128
|
+
onInitialized,
|
|
129
|
+
origin,
|
|
130
|
+
trackedOrigins,
|
|
131
|
+
update
|
|
132
|
+
} = params;
|
|
120
133
|
const updates = typeof update === "string" ? [update] : update;
|
|
134
|
+
this.trackOrigins({ captureTimeout, trackedOrigins });
|
|
121
135
|
if (!updates.length)
|
|
122
136
|
return this;
|
|
123
137
|
if (this.initialized) {
|
|
@@ -132,8 +146,13 @@ var CrdtManager = class {
|
|
|
132
146
|
_doc.destroy();
|
|
133
147
|
}
|
|
134
148
|
onInitialized == null ? void 0 : onInitialized();
|
|
149
|
+
this.trackOrigins({ captureTimeout, trackedOrigins });
|
|
135
150
|
return this;
|
|
136
151
|
}
|
|
152
|
+
trackOrigins(options) {
|
|
153
|
+
const { captureTimeout, trackedOrigins } = options;
|
|
154
|
+
this.doc.trackOrigins({ captureTimeout, trackedOrigins });
|
|
155
|
+
}
|
|
137
156
|
_applyDocUpdates(yjsDoc, updates, origin) {
|
|
138
157
|
yjsDoc.transact(() => {
|
|
139
158
|
updates.reduce((acc, _update) => acc.applyUpdate(_update), yjsDoc);
|
|
@@ -146,6 +165,7 @@ var CrdtManager = class {
|
|
|
146
165
|
var import_wonka = require("wonka");
|
|
147
166
|
var CrdtNotifier = class {
|
|
148
167
|
constructor() {
|
|
168
|
+
this.rootSubject = (0, import_wonka.makeSubject)();
|
|
149
169
|
this.subjects = /* @__PURE__ */ new Map();
|
|
150
170
|
}
|
|
151
171
|
subject(key) {
|
|
@@ -157,6 +177,9 @@ var CrdtNotifier = class {
|
|
|
157
177
|
this.subjects.set(key, newSubject);
|
|
158
178
|
return newSubject;
|
|
159
179
|
}
|
|
180
|
+
subcribeRoot(callback) {
|
|
181
|
+
return (0, import_wonka.subscribe)(callback)(this.rootSubject.source).unsubscribe;
|
|
182
|
+
}
|
|
160
183
|
subscribe(key, callback) {
|
|
161
184
|
const subject = this.subject(key);
|
|
162
185
|
return (0, import_wonka.subscribe)(callback)(subject.source).unsubscribe;
|
|
@@ -379,7 +402,8 @@ var ADD_TO_STORAGE_STATE_DEBOUNCE_MS = 1e3;
|
|
|
379
402
|
var HEARTBEAT_INTERVAL_MS = 1e4;
|
|
380
403
|
var PONG_TIMEOUT_MS = 2e3;
|
|
381
404
|
var RECONNECT_TIMEOUT_MS = 3e4;
|
|
382
|
-
var
|
|
405
|
+
var ORIGIN_INITIALIZED = "$INITIALIZED";
|
|
406
|
+
var ORIGIN_STORAGE_UPDATED = "$STORAGE_UPDATED";
|
|
383
407
|
var DEFAULT_PLUV_CLIENT_ADDON = (input) => ({
|
|
384
408
|
storage: new StorageStore(input.room.id)
|
|
385
409
|
});
|
|
@@ -388,14 +412,17 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
388
412
|
const {
|
|
389
413
|
addons = [],
|
|
390
414
|
authEndpoint,
|
|
415
|
+
captureTimeout,
|
|
391
416
|
debug = false,
|
|
392
417
|
initialPresence,
|
|
393
418
|
initialStorage,
|
|
394
419
|
onAuthorizationFail,
|
|
395
420
|
presence,
|
|
421
|
+
trackedOrigins,
|
|
396
422
|
wsEndpoint
|
|
397
423
|
} = options;
|
|
398
424
|
super(room);
|
|
425
|
+
this._captureTimeout = null;
|
|
399
426
|
this._crdtNotifier = new CrdtNotifier();
|
|
400
427
|
this._eventNotifier = new EventNotifier();
|
|
401
428
|
this._intervals = {
|
|
@@ -422,8 +449,15 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
422
449
|
pong: null,
|
|
423
450
|
reconnect: null
|
|
424
451
|
};
|
|
452
|
+
this._trackedOrigins = null;
|
|
425
453
|
this._windowListeners = null;
|
|
426
454
|
this._wsListeners = null;
|
|
455
|
+
this.canRedo = () => {
|
|
456
|
+
return !!this._crdtManager.doc.canRedo();
|
|
457
|
+
};
|
|
458
|
+
this.canUndo = () => {
|
|
459
|
+
return !!this._crdtManager.doc.canUndo();
|
|
460
|
+
};
|
|
427
461
|
this.event = (event, callback) => {
|
|
428
462
|
return this._eventNotifier.subscribe(event, callback);
|
|
429
463
|
};
|
|
@@ -446,12 +480,29 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
446
480
|
this.other = (connectionId, callback) => {
|
|
447
481
|
return this._otherNotifier.subscribe(connectionId, callback);
|
|
448
482
|
};
|
|
483
|
+
this.redo = () => {
|
|
484
|
+
this._crdtManager.doc.redo();
|
|
485
|
+
};
|
|
449
486
|
this.storage = (key, fn) => {
|
|
450
487
|
return this._crdtNotifier.subscribe(key, fn);
|
|
451
488
|
};
|
|
489
|
+
this.storageRoot = (fn) => {
|
|
490
|
+
return this._crdtNotifier.subcribeRoot(fn);
|
|
491
|
+
};
|
|
452
492
|
this.subscribe = (name, callback) => {
|
|
453
493
|
return this._stateNotifier.subscribe(name, callback);
|
|
454
494
|
};
|
|
495
|
+
this.transact = (fn, origin) => {
|
|
496
|
+
const _origin = origin != null ? origin : this._state.connection.id;
|
|
497
|
+
if (typeof _origin !== "string")
|
|
498
|
+
return;
|
|
499
|
+
this._crdtManager.doc.transact(() => {
|
|
500
|
+
fn(this._crdtManager.doc.storage);
|
|
501
|
+
}, _origin);
|
|
502
|
+
};
|
|
503
|
+
this.undo = () => {
|
|
504
|
+
this._crdtManager.doc.undo();
|
|
505
|
+
};
|
|
455
506
|
this.updateMyPresence = (presence) => {
|
|
456
507
|
var _a;
|
|
457
508
|
this._usersManager.updateMyPresence(presence);
|
|
@@ -501,7 +552,13 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
501
552
|
initialPresence,
|
|
502
553
|
presence
|
|
503
554
|
});
|
|
504
|
-
this._crdtManager = new CrdtManager({
|
|
555
|
+
this._crdtManager = new CrdtManager({
|
|
556
|
+
captureTimeout,
|
|
557
|
+
initialStorage,
|
|
558
|
+
trackedOrigins
|
|
559
|
+
});
|
|
560
|
+
this._captureTimeout = captureTimeout != null ? captureTimeout : null;
|
|
561
|
+
this._trackedOrigins = trackedOrigins != null ? trackedOrigins : null;
|
|
505
562
|
}
|
|
506
563
|
get webSocket() {
|
|
507
564
|
return this._state.webSocket;
|
|
@@ -532,7 +589,6 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
532
589
|
});
|
|
533
590
|
yield this._storageStore.initialize();
|
|
534
591
|
yield this._applyStorageStore();
|
|
535
|
-
console.log(this._getWsEndpoint(this.id));
|
|
536
592
|
const url = new URL(this._getWsEndpoint(this.id));
|
|
537
593
|
let authToken = null;
|
|
538
594
|
let webSocket;
|
|
@@ -588,12 +644,16 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
588
644
|
}
|
|
589
645
|
_applyStorageStore() {
|
|
590
646
|
return __async(this, null, function* () {
|
|
647
|
+
var _a;
|
|
591
648
|
const updates = yield this._storageStore.getUpdates();
|
|
649
|
+
const trackedOrigins = this._getTrackedOrigins();
|
|
592
650
|
this._crdtManager.initialize({
|
|
651
|
+
captureTimeout: (_a = this._captureTimeout) != null ? _a : void 0,
|
|
593
652
|
onInitialized: () => {
|
|
594
653
|
this._observeCrdt();
|
|
595
654
|
},
|
|
596
|
-
origin:
|
|
655
|
+
origin: ORIGIN_INITIALIZED,
|
|
656
|
+
trackedOrigins: trackedOrigins != null ? trackedOrigins : void 0,
|
|
597
657
|
update: updates
|
|
598
658
|
});
|
|
599
659
|
this._emitSharedTypes();
|
|
@@ -712,10 +772,15 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
712
772
|
}
|
|
713
773
|
_emitSharedTypes() {
|
|
714
774
|
const sharedTypes = this._crdtManager.doc.getSharedTypes();
|
|
715
|
-
Object.entries(sharedTypes).
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
775
|
+
const storageRoot = Object.entries(sharedTypes).reduce(
|
|
776
|
+
(acc, [prop, sharedType]) => {
|
|
777
|
+
const serialized = sharedType.toJSON();
|
|
778
|
+
this._crdtNotifier.subject(prop).next(serialized);
|
|
779
|
+
return __spreadProps(__spreadValues({}, acc), { [prop]: serialized });
|
|
780
|
+
},
|
|
781
|
+
{}
|
|
782
|
+
);
|
|
783
|
+
this._crdtNotifier.rootSubject.next(storageRoot);
|
|
719
784
|
}
|
|
720
785
|
_getAuthFetchOptions(room) {
|
|
721
786
|
if (typeof this._endpoints.authEndpoint === "undefined")
|
|
@@ -754,6 +819,11 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
754
819
|
}
|
|
755
820
|
});
|
|
756
821
|
}
|
|
822
|
+
_getTrackedOrigins() {
|
|
823
|
+
var _a;
|
|
824
|
+
const connectionId = this._state.connection.id;
|
|
825
|
+
return !connectionId ? this._trackedOrigins : [connectionId, ...(_a = this._trackedOrigins) != null ? _a : []];
|
|
826
|
+
}
|
|
757
827
|
_getWsEndpoint(room) {
|
|
758
828
|
switch (typeof this._endpoints.wsEndpoint) {
|
|
759
829
|
case "undefined":
|
|
@@ -850,17 +920,21 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
850
920
|
}
|
|
851
921
|
_handleStorageReceivedMessage(message) {
|
|
852
922
|
return __async(this, null, function* () {
|
|
923
|
+
var _a;
|
|
853
924
|
const { connectionId } = message;
|
|
854
925
|
if (!connectionId)
|
|
855
926
|
return;
|
|
856
927
|
if (!this._state.webSocket)
|
|
857
928
|
throw new Error("Could not find WebSocket");
|
|
858
929
|
const data = message.data;
|
|
930
|
+
const trackedOrigins = this._getTrackedOrigins();
|
|
859
931
|
this._crdtManager.initialize({
|
|
932
|
+
captureTimeout: (_a = this._captureTimeout) != null ? _a : void 0,
|
|
860
933
|
onInitialized: () => __async(this, null, function* () {
|
|
861
934
|
this._observeCrdt();
|
|
862
935
|
}),
|
|
863
|
-
origin:
|
|
936
|
+
origin: ORIGIN_INITIALIZED,
|
|
937
|
+
trackedOrigins: trackedOrigins != null ? trackedOrigins : void 0,
|
|
864
938
|
update: data.state
|
|
865
939
|
});
|
|
866
940
|
const encodedState = this._crdtManager.doc.encodeStateAsUpdate();
|
|
@@ -869,7 +943,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
869
943
|
const update = this._crdtManager.doc.encodeStateAsUpdate();
|
|
870
944
|
this._sendMessage({
|
|
871
945
|
type: "$UPDATE_STORAGE",
|
|
872
|
-
data: { origin:
|
|
946
|
+
data: { origin: ORIGIN_INITIALIZED, update }
|
|
873
947
|
});
|
|
874
948
|
});
|
|
875
949
|
}
|
|
@@ -882,14 +956,19 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
882
956
|
const data = message.data;
|
|
883
957
|
if (!this._crdtManager)
|
|
884
958
|
return;
|
|
885
|
-
this._crdtManager.doc.applyUpdate(data.state,
|
|
959
|
+
this._crdtManager.doc.applyUpdate(data.state, ORIGIN_STORAGE_UPDATED);
|
|
886
960
|
const sharedTypes = this._crdtManager.doc.getSharedTypes();
|
|
887
|
-
Object.entries(sharedTypes).
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
961
|
+
const storageRoot = Object.entries(sharedTypes).reduce(
|
|
962
|
+
(acc, [prop, sharedType]) => {
|
|
963
|
+
if (!this._crdtManager)
|
|
964
|
+
return acc;
|
|
965
|
+
const serialized = sharedType.toJSON();
|
|
966
|
+
this._crdtNotifier.subject(prop).next(serialized);
|
|
967
|
+
return __spreadProps(__spreadValues({}, acc), { [prop]: serialized });
|
|
968
|
+
},
|
|
969
|
+
{}
|
|
970
|
+
);
|
|
971
|
+
this._crdtNotifier.rootSubject.next(storageRoot);
|
|
893
972
|
}
|
|
894
973
|
_handleUserJoinedMessage(message) {
|
|
895
974
|
const { connectionId } = message;
|
|
@@ -938,7 +1017,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
938
1017
|
const origin = _origin != null ? _origin : null;
|
|
939
1018
|
this._addToStorageStore(update);
|
|
940
1019
|
this._emitSharedTypes();
|
|
941
|
-
if (origin ===
|
|
1020
|
+
if (origin === ORIGIN_INITIALIZED || origin === this)
|
|
942
1021
|
return;
|
|
943
1022
|
if (!this._state.webSocket)
|
|
944
1023
|
return;
|
|
@@ -946,7 +1025,7 @@ var PluvRoom = class extends AbstractRoom {
|
|
|
946
1025
|
return;
|
|
947
1026
|
if (this._state.webSocket.readyState !== WebSocket.OPEN)
|
|
948
1027
|
return;
|
|
949
|
-
if (origin ===
|
|
1028
|
+
if (origin === ORIGIN_STORAGE_UPDATED)
|
|
950
1029
|
return;
|
|
951
1030
|
this._sendMessage({
|
|
952
1031
|
type: "$UPDATE_STORAGE",
|
|
@@ -1236,6 +1315,14 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1236
1315
|
this._subscriptions = {
|
|
1237
1316
|
observeCrdt: null
|
|
1238
1317
|
};
|
|
1318
|
+
this.canRedo = () => {
|
|
1319
|
+
var _a;
|
|
1320
|
+
return !!((_a = this._crdtManager) == null ? void 0 : _a.doc.canRedo());
|
|
1321
|
+
};
|
|
1322
|
+
this.canUndo = () => {
|
|
1323
|
+
var _a;
|
|
1324
|
+
return !!((_a = this._crdtManager) == null ? void 0 : _a.doc.canUndo());
|
|
1325
|
+
};
|
|
1239
1326
|
this.event = (event, callback) => {
|
|
1240
1327
|
return this._eventNotifier.subscribe(event, callback);
|
|
1241
1328
|
};
|
|
@@ -1258,12 +1345,34 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1258
1345
|
this.other = (connectionId, callback) => {
|
|
1259
1346
|
return this._otherNotifier.subscribe(connectionId, callback);
|
|
1260
1347
|
};
|
|
1348
|
+
this.redo = () => {
|
|
1349
|
+
var _a;
|
|
1350
|
+
(_a = this._crdtManager) == null ? void 0 : _a.doc.redo();
|
|
1351
|
+
};
|
|
1261
1352
|
this.storage = (key, fn) => {
|
|
1262
1353
|
return this._crdtNotifier.subscribe(key, fn);
|
|
1263
1354
|
};
|
|
1355
|
+
this.storageRoot = (fn) => {
|
|
1356
|
+
return this._crdtNotifier.subcribeRoot(fn);
|
|
1357
|
+
};
|
|
1264
1358
|
this.subscribe = (name, callback) => {
|
|
1265
1359
|
return this._stateNotifier.subscribe(name, callback);
|
|
1266
1360
|
};
|
|
1361
|
+
this.transact = (fn, origin) => {
|
|
1362
|
+
const _origin = origin != null ? origin : this._state.connection.id;
|
|
1363
|
+
const crdtManager = this._crdtManager;
|
|
1364
|
+
if (typeof _origin !== "string")
|
|
1365
|
+
return;
|
|
1366
|
+
if (!crdtManager)
|
|
1367
|
+
return;
|
|
1368
|
+
crdtManager.doc.transact(() => {
|
|
1369
|
+
fn(crdtManager.doc.storage);
|
|
1370
|
+
}, _origin);
|
|
1371
|
+
};
|
|
1372
|
+
this.undo = () => {
|
|
1373
|
+
var _a;
|
|
1374
|
+
(_a = this._crdtManager) == null ? void 0 : _a.doc.undo();
|
|
1375
|
+
};
|
|
1267
1376
|
this.updateMyPresence = (presence) => {
|
|
1268
1377
|
var _a;
|
|
1269
1378
|
this._usersManager.updateMyPresence(presence);
|
|
@@ -1315,12 +1424,17 @@ var MockedRoom = class extends AbstractRoom {
|
|
|
1315
1424
|
if (origin === "$STORAGE_UPDATED")
|
|
1316
1425
|
return;
|
|
1317
1426
|
const sharedTypes = this._crdtManager.doc.getSharedTypes();
|
|
1318
|
-
Object.entries(sharedTypes).
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1427
|
+
const storageRoot = Object.entries(sharedTypes).reduce(
|
|
1428
|
+
(acc, [prop, sharedType]) => {
|
|
1429
|
+
if (!this._crdtManager)
|
|
1430
|
+
return acc;
|
|
1431
|
+
const serialized = sharedType.toJSON();
|
|
1432
|
+
this._crdtNotifier.subject(prop).next(serialized);
|
|
1433
|
+
return __spreadProps(__spreadValues({}, acc), { [prop]: serialized });
|
|
1434
|
+
},
|
|
1435
|
+
{}
|
|
1436
|
+
);
|
|
1437
|
+
this._crdtNotifier.rootSubject.next(storageRoot);
|
|
1324
1438
|
}
|
|
1325
1439
|
);
|
|
1326
1440
|
this._subscriptions.observeCrdt = unsubscribe;
|