y-partyserver 2.1.0 → 2.1.2
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/chunk-C0xms8kb.cjs +34 -0
- package/dist/provider/index.cjs +489 -0
- package/dist/provider/index.cjs.map +1 -0
- package/dist/provider/index.d.cts +133 -0
- package/dist/provider/index.js +422 -285
- package/dist/provider/react.cjs +34 -0
- package/dist/provider/react.cjs.map +1 -0
- package/dist/provider/react.d.cts +15 -0
- package/dist/provider/react.js +24 -13
- package/dist/server/index.cjs +366 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +48 -0
- package/dist/server/index.d.ts +13 -41
- package/dist/server/index.js +333 -227
- package/dist/server/index.js.map +1 -1
- package/package.json +23 -11
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
|
|
29
|
+
Object.defineProperty(exports, '__toESM', {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
get: function () {
|
|
32
|
+
return __toESM;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_chunk = require("../chunk-C0xms8kb.cjs");
|
|
6
|
+
let lib0_decoding = require("lib0/decoding");
|
|
7
|
+
lib0_decoding = require_chunk.__toESM(lib0_decoding);
|
|
8
|
+
let lib0_encoding = require("lib0/encoding");
|
|
9
|
+
lib0_encoding = require_chunk.__toESM(lib0_encoding);
|
|
10
|
+
let y_protocols_awareness = require("y-protocols/awareness");
|
|
11
|
+
y_protocols_awareness = require_chunk.__toESM(y_protocols_awareness);
|
|
12
|
+
let y_protocols_sync = require("y-protocols/sync");
|
|
13
|
+
y_protocols_sync = require_chunk.__toESM(y_protocols_sync);
|
|
14
|
+
let yjs = require("yjs");
|
|
15
|
+
let lib0_broadcastchannel = require("lib0/broadcastchannel");
|
|
16
|
+
lib0_broadcastchannel = require_chunk.__toESM(lib0_broadcastchannel);
|
|
17
|
+
let lib0_math = require("lib0/math");
|
|
18
|
+
lib0_math = require_chunk.__toESM(lib0_math);
|
|
19
|
+
let lib0_observable = require("lib0/observable");
|
|
20
|
+
let lib0_time = require("lib0/time");
|
|
21
|
+
lib0_time = require_chunk.__toESM(lib0_time);
|
|
22
|
+
let lib0_url = require("lib0/url");
|
|
23
|
+
lib0_url = require_chunk.__toESM(lib0_url);
|
|
24
|
+
let nanoid = require("nanoid");
|
|
25
|
+
let y_protocols_auth = require("y-protocols/auth");
|
|
26
|
+
y_protocols_auth = require_chunk.__toESM(y_protocols_auth);
|
|
27
|
+
|
|
28
|
+
//#region src/provider/index.ts
|
|
29
|
+
const messageSync = 0;
|
|
30
|
+
const messageQueryAwareness = 3;
|
|
31
|
+
const messageAwareness = 1;
|
|
32
|
+
const messageAuth = 2;
|
|
33
|
+
const DEFAULT_DISABLE_BC = typeof window === "undefined";
|
|
34
|
+
const messageHandlers = [];
|
|
35
|
+
messageHandlers[messageSync] = (
|
|
36
|
+
encoder,
|
|
37
|
+
decoder,
|
|
38
|
+
provider,
|
|
39
|
+
emitSynced,
|
|
40
|
+
_messageType
|
|
41
|
+
) => {
|
|
42
|
+
lib0_encoding.writeVarUint(encoder, messageSync);
|
|
43
|
+
const syncMessageType = y_protocols_sync.readSyncMessage(
|
|
44
|
+
decoder,
|
|
45
|
+
encoder,
|
|
46
|
+
provider.doc,
|
|
47
|
+
provider
|
|
48
|
+
);
|
|
49
|
+
if (
|
|
50
|
+
emitSynced &&
|
|
51
|
+
syncMessageType === y_protocols_sync.messageYjsSyncStep2 &&
|
|
52
|
+
!provider.synced
|
|
53
|
+
)
|
|
54
|
+
provider.synced = true;
|
|
55
|
+
};
|
|
56
|
+
messageHandlers[messageQueryAwareness] = (
|
|
57
|
+
encoder,
|
|
58
|
+
_decoder,
|
|
59
|
+
provider,
|
|
60
|
+
_emitSynced,
|
|
61
|
+
_messageType
|
|
62
|
+
) => {
|
|
63
|
+
lib0_encoding.writeVarUint(encoder, messageAwareness);
|
|
64
|
+
lib0_encoding.writeVarUint8Array(
|
|
65
|
+
encoder,
|
|
66
|
+
y_protocols_awareness.encodeAwarenessUpdate(
|
|
67
|
+
provider.awareness,
|
|
68
|
+
Array.from(provider.awareness.getStates().keys())
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
messageHandlers[messageAwareness] = (
|
|
73
|
+
_encoder,
|
|
74
|
+
decoder,
|
|
75
|
+
provider,
|
|
76
|
+
_emitSynced,
|
|
77
|
+
_messageType
|
|
78
|
+
) => {
|
|
79
|
+
y_protocols_awareness.applyAwarenessUpdate(
|
|
80
|
+
provider.awareness,
|
|
81
|
+
lib0_decoding.readVarUint8Array(decoder),
|
|
82
|
+
provider
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
messageHandlers[messageAuth] = (
|
|
86
|
+
_encoder,
|
|
87
|
+
decoder,
|
|
88
|
+
provider,
|
|
89
|
+
_emitSynced,
|
|
90
|
+
_messageType
|
|
91
|
+
) => {
|
|
92
|
+
y_protocols_auth.readAuthMessage(decoder, provider.doc, (_ydoc, reason) =>
|
|
93
|
+
permissionDeniedHandler(provider, reason)
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
function permissionDeniedHandler(provider, reason) {
|
|
97
|
+
console.warn(`Permission denied to access ${provider.url}.\n${reason}`);
|
|
98
|
+
}
|
|
99
|
+
function readMessage(provider, buf, emitSynced) {
|
|
100
|
+
const decoder = lib0_decoding.createDecoder(buf);
|
|
101
|
+
const encoder = lib0_encoding.createEncoder();
|
|
102
|
+
const messageType = lib0_decoding.readVarUint(decoder);
|
|
103
|
+
const messageHandler = provider.messageHandlers[messageType];
|
|
104
|
+
if (messageHandler)
|
|
105
|
+
messageHandler(encoder, decoder, provider, emitSynced, messageType);
|
|
106
|
+
else console.error("Unable to compute message");
|
|
107
|
+
return encoder;
|
|
108
|
+
}
|
|
109
|
+
function setupWS(provider) {
|
|
110
|
+
if (provider.shouldConnect && provider.ws === null) {
|
|
111
|
+
if (!provider._WS)
|
|
112
|
+
throw new Error(
|
|
113
|
+
"No WebSocket implementation available, did you forget to pass options.WebSocketPolyfill?"
|
|
114
|
+
);
|
|
115
|
+
const websocket = new provider._WS(provider.url);
|
|
116
|
+
websocket.binaryType = "arraybuffer";
|
|
117
|
+
provider.ws = websocket;
|
|
118
|
+
provider.wsconnecting = true;
|
|
119
|
+
provider.wsconnected = false;
|
|
120
|
+
provider.synced = false;
|
|
121
|
+
websocket.addEventListener("message", (event) => {
|
|
122
|
+
if (typeof event.data === "string") {
|
|
123
|
+
if (event.data.startsWith("__YPS:")) {
|
|
124
|
+
const customMessage = event.data.slice(6);
|
|
125
|
+
provider.emit("custom-message", [customMessage]);
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
provider.wsLastMessageReceived = lib0_time.getUnixTime();
|
|
130
|
+
const encoder = readMessage(provider, new Uint8Array(event.data), true);
|
|
131
|
+
if (lib0_encoding.length(encoder) > 1)
|
|
132
|
+
websocket.send(lib0_encoding.toUint8Array(encoder));
|
|
133
|
+
});
|
|
134
|
+
websocket.addEventListener("error", (event) => {
|
|
135
|
+
provider.emit("connection-error", [event, provider]);
|
|
136
|
+
});
|
|
137
|
+
websocket.addEventListener("close", (event) => {
|
|
138
|
+
provider.emit("connection-close", [event, provider]);
|
|
139
|
+
provider.ws = null;
|
|
140
|
+
provider.wsconnecting = false;
|
|
141
|
+
if (provider.wsconnected) {
|
|
142
|
+
provider.wsconnected = false;
|
|
143
|
+
provider.synced = false;
|
|
144
|
+
const removedClients = Array.from(
|
|
145
|
+
provider.awareness.getStates().keys()
|
|
146
|
+
).filter((client) => client !== provider.doc.clientID);
|
|
147
|
+
y_protocols_awareness.removeAwarenessStates(
|
|
148
|
+
provider.awareness,
|
|
149
|
+
removedClients,
|
|
150
|
+
provider
|
|
151
|
+
);
|
|
152
|
+
for (const clientID of removedClients)
|
|
153
|
+
provider.awareness.meta.delete(clientID);
|
|
154
|
+
provider.emit("status", [{ status: "disconnected" }]);
|
|
155
|
+
} else provider.wsUnsuccessfulReconnects++;
|
|
156
|
+
setTimeout(
|
|
157
|
+
setupWS,
|
|
158
|
+
lib0_math.min(
|
|
159
|
+
lib0_math.pow(2, provider.wsUnsuccessfulReconnects) * 100,
|
|
160
|
+
provider.maxBackoffTime
|
|
161
|
+
),
|
|
162
|
+
provider
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
websocket.addEventListener("open", () => {
|
|
166
|
+
provider.wsLastMessageReceived = lib0_time.getUnixTime();
|
|
167
|
+
provider.wsconnecting = false;
|
|
168
|
+
provider.wsconnected = true;
|
|
169
|
+
provider.wsUnsuccessfulReconnects = 0;
|
|
170
|
+
provider.emit("status", [{ status: "connected" }]);
|
|
171
|
+
const encoder = lib0_encoding.createEncoder();
|
|
172
|
+
lib0_encoding.writeVarUint(encoder, messageSync);
|
|
173
|
+
y_protocols_sync.writeSyncStep1(encoder, provider.doc);
|
|
174
|
+
websocket.send(lib0_encoding.toUint8Array(encoder));
|
|
175
|
+
if (provider.awareness.getLocalState() !== null) {
|
|
176
|
+
provider.awareness.setLocalState(provider.awareness.getLocalState());
|
|
177
|
+
const encoderAwarenessState = lib0_encoding.createEncoder();
|
|
178
|
+
lib0_encoding.writeVarUint(encoderAwarenessState, messageAwareness);
|
|
179
|
+
lib0_encoding.writeVarUint8Array(
|
|
180
|
+
encoderAwarenessState,
|
|
181
|
+
y_protocols_awareness.encodeAwarenessUpdate(provider.awareness, [
|
|
182
|
+
provider.doc.clientID
|
|
183
|
+
])
|
|
184
|
+
);
|
|
185
|
+
websocket.send(lib0_encoding.toUint8Array(encoderAwarenessState));
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
provider.emit("status", [{ status: "connecting" }]);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function broadcastMessage(provider, buf) {
|
|
192
|
+
const ws = provider.ws;
|
|
193
|
+
if (provider.wsconnected && ws && ws.readyState === ws.OPEN) ws.send(buf);
|
|
194
|
+
if (provider.bcconnected)
|
|
195
|
+
lib0_broadcastchannel.publish(provider.bcChannel, buf, provider);
|
|
196
|
+
}
|
|
197
|
+
const DefaultWebSocket = typeof WebSocket === "undefined" ? null : WebSocket;
|
|
198
|
+
/**
|
|
199
|
+
* Websocket Provider for Yjs. Creates a websocket connection to sync the shared document.
|
|
200
|
+
* The document name is attached to the provided url. I.e. the following example
|
|
201
|
+
* creates a websocket connection to http://localhost:1234/my-document-name
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* import * as Y from 'yjs'
|
|
205
|
+
* import { WebsocketProvider } from 'y-websocket'
|
|
206
|
+
* const doc = new Y.Doc()
|
|
207
|
+
* const provider = new WebsocketProvider('http://localhost:1234', 'my-document-name', doc)
|
|
208
|
+
*
|
|
209
|
+
* @extends {Observable<string>}
|
|
210
|
+
*/
|
|
211
|
+
var WebsocketProvider = class extends lib0_observable.Observable {
|
|
212
|
+
maxBackoffTime;
|
|
213
|
+
bcChannel;
|
|
214
|
+
url;
|
|
215
|
+
roomname;
|
|
216
|
+
doc;
|
|
217
|
+
_WS;
|
|
218
|
+
awareness;
|
|
219
|
+
wsconnected;
|
|
220
|
+
wsconnecting;
|
|
221
|
+
bcconnected;
|
|
222
|
+
disableBc;
|
|
223
|
+
wsUnsuccessfulReconnects;
|
|
224
|
+
messageHandlers;
|
|
225
|
+
_synced;
|
|
226
|
+
ws;
|
|
227
|
+
wsLastMessageReceived;
|
|
228
|
+
shouldConnect;
|
|
229
|
+
_resyncInterval;
|
|
230
|
+
_bcSubscriber;
|
|
231
|
+
_updateHandler;
|
|
232
|
+
_awarenessUpdateHandler;
|
|
233
|
+
_unloadHandler;
|
|
234
|
+
constructor(
|
|
235
|
+
serverUrl,
|
|
236
|
+
roomname,
|
|
237
|
+
doc,
|
|
238
|
+
{
|
|
239
|
+
connect = true,
|
|
240
|
+
awareness = new y_protocols_awareness.Awareness(doc),
|
|
241
|
+
params = {},
|
|
242
|
+
isPrefixedUrl = false,
|
|
243
|
+
WebSocketPolyfill = DefaultWebSocket,
|
|
244
|
+
resyncInterval = -1,
|
|
245
|
+
maxBackoffTime = 2500,
|
|
246
|
+
disableBc = DEFAULT_DISABLE_BC
|
|
247
|
+
} = {}
|
|
248
|
+
) {
|
|
249
|
+
super();
|
|
250
|
+
while (serverUrl[serverUrl.length - 1] === "/")
|
|
251
|
+
serverUrl = serverUrl.slice(0, serverUrl.length - 1);
|
|
252
|
+
const encodedParams = lib0_url.encodeQueryParams(params);
|
|
253
|
+
this.maxBackoffTime = maxBackoffTime;
|
|
254
|
+
this.bcChannel = `${serverUrl}/${roomname}`;
|
|
255
|
+
this.url = isPrefixedUrl
|
|
256
|
+
? serverUrl
|
|
257
|
+
: `${serverUrl}/${roomname}${encodedParams.length === 0 ? "" : `?${encodedParams}`}`;
|
|
258
|
+
this.roomname = roomname;
|
|
259
|
+
this.doc = doc;
|
|
260
|
+
this._WS = WebSocketPolyfill;
|
|
261
|
+
this.awareness = awareness;
|
|
262
|
+
this.wsconnected = false;
|
|
263
|
+
this.wsconnecting = false;
|
|
264
|
+
this.bcconnected = false;
|
|
265
|
+
this.disableBc = disableBc;
|
|
266
|
+
this.wsUnsuccessfulReconnects = 0;
|
|
267
|
+
this.messageHandlers = messageHandlers.slice();
|
|
268
|
+
this._synced = false;
|
|
269
|
+
this.ws = null;
|
|
270
|
+
this.wsLastMessageReceived = 0;
|
|
271
|
+
this.shouldConnect = connect;
|
|
272
|
+
this._resyncInterval = 0;
|
|
273
|
+
if (resyncInterval > 0)
|
|
274
|
+
this._resyncInterval = setInterval(() => {
|
|
275
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
276
|
+
const encoder = lib0_encoding.createEncoder();
|
|
277
|
+
lib0_encoding.writeVarUint(encoder, messageSync);
|
|
278
|
+
y_protocols_sync.writeSyncStep1(encoder, doc);
|
|
279
|
+
this.ws.send(lib0_encoding.toUint8Array(encoder));
|
|
280
|
+
}
|
|
281
|
+
}, resyncInterval);
|
|
282
|
+
this._bcSubscriber = (data, origin) => {
|
|
283
|
+
if (origin !== this) {
|
|
284
|
+
const encoder = readMessage(this, new Uint8Array(data), false);
|
|
285
|
+
if (lib0_encoding.length(encoder) > 1)
|
|
286
|
+
lib0_broadcastchannel.publish(
|
|
287
|
+
this.bcChannel,
|
|
288
|
+
lib0_encoding.toUint8Array(encoder),
|
|
289
|
+
this
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Listens to Yjs updates and sends them to remote peers (ws and broadcastchannel)
|
|
295
|
+
*/
|
|
296
|
+
this._updateHandler = (update, origin) => {
|
|
297
|
+
if (origin !== this) {
|
|
298
|
+
const encoder = lib0_encoding.createEncoder();
|
|
299
|
+
lib0_encoding.writeVarUint(encoder, messageSync);
|
|
300
|
+
y_protocols_sync.writeUpdate(encoder, update);
|
|
301
|
+
broadcastMessage(this, lib0_encoding.toUint8Array(encoder));
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
this.doc.on("update", this._updateHandler);
|
|
305
|
+
this._awarenessUpdateHandler = ({ added, updated, removed }, _origin) => {
|
|
306
|
+
const changedClients = added.concat(updated).concat(removed);
|
|
307
|
+
const encoder = lib0_encoding.createEncoder();
|
|
308
|
+
lib0_encoding.writeVarUint(encoder, messageAwareness);
|
|
309
|
+
lib0_encoding.writeVarUint8Array(
|
|
310
|
+
encoder,
|
|
311
|
+
y_protocols_awareness.encodeAwarenessUpdate(awareness, changedClients)
|
|
312
|
+
);
|
|
313
|
+
broadcastMessage(this, lib0_encoding.toUint8Array(encoder));
|
|
314
|
+
};
|
|
315
|
+
this._unloadHandler = () => {
|
|
316
|
+
y_protocols_awareness.removeAwarenessStates(
|
|
317
|
+
this.awareness,
|
|
318
|
+
[doc.clientID],
|
|
319
|
+
"window unload"
|
|
320
|
+
);
|
|
321
|
+
};
|
|
322
|
+
if (typeof window !== "undefined")
|
|
323
|
+
window.addEventListener("unload", this._unloadHandler);
|
|
324
|
+
else if (typeof process !== "undefined" && typeof process.on === "function")
|
|
325
|
+
process.on("exit", this._unloadHandler);
|
|
326
|
+
awareness.on("change", this._awarenessUpdateHandler);
|
|
327
|
+
clearInterval(awareness._checkInterval);
|
|
328
|
+
if (connect) this.connect();
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* @type {boolean}
|
|
332
|
+
*/
|
|
333
|
+
get synced() {
|
|
334
|
+
return this._synced;
|
|
335
|
+
}
|
|
336
|
+
set synced(state) {
|
|
337
|
+
if (this._synced !== state) {
|
|
338
|
+
this._synced = state;
|
|
339
|
+
this.emit("synced", [state]);
|
|
340
|
+
this.emit("sync", [state]);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
destroy() {
|
|
344
|
+
if (this._resyncInterval !== 0) clearInterval(this._resyncInterval);
|
|
345
|
+
this.disconnect();
|
|
346
|
+
if (typeof window !== "undefined")
|
|
347
|
+
window.removeEventListener("unload", this._unloadHandler);
|
|
348
|
+
else if (
|
|
349
|
+
typeof process !== "undefined" &&
|
|
350
|
+
typeof process.off === "function"
|
|
351
|
+
)
|
|
352
|
+
process.off("exit", this._unloadHandler);
|
|
353
|
+
this.awareness.off("change", this._awarenessUpdateHandler);
|
|
354
|
+
this.doc.off("update", this._updateHandler);
|
|
355
|
+
super.destroy();
|
|
356
|
+
}
|
|
357
|
+
connectBc() {
|
|
358
|
+
if (this.disableBc) return;
|
|
359
|
+
if (!this.bcconnected) {
|
|
360
|
+
lib0_broadcastchannel.subscribe(this.bcChannel, this._bcSubscriber);
|
|
361
|
+
this.bcconnected = true;
|
|
362
|
+
}
|
|
363
|
+
const encoderSync = lib0_encoding.createEncoder();
|
|
364
|
+
lib0_encoding.writeVarUint(encoderSync, messageSync);
|
|
365
|
+
y_protocols_sync.writeSyncStep1(encoderSync, this.doc);
|
|
366
|
+
lib0_broadcastchannel.publish(
|
|
367
|
+
this.bcChannel,
|
|
368
|
+
lib0_encoding.toUint8Array(encoderSync),
|
|
369
|
+
this
|
|
370
|
+
);
|
|
371
|
+
const encoderState = lib0_encoding.createEncoder();
|
|
372
|
+
lib0_encoding.writeVarUint(encoderState, messageSync);
|
|
373
|
+
y_protocols_sync.writeSyncStep2(encoderState, this.doc);
|
|
374
|
+
lib0_broadcastchannel.publish(
|
|
375
|
+
this.bcChannel,
|
|
376
|
+
lib0_encoding.toUint8Array(encoderState),
|
|
377
|
+
this
|
|
378
|
+
);
|
|
379
|
+
const encoderAwarenessQuery = lib0_encoding.createEncoder();
|
|
380
|
+
lib0_encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness);
|
|
381
|
+
lib0_broadcastchannel.publish(
|
|
382
|
+
this.bcChannel,
|
|
383
|
+
lib0_encoding.toUint8Array(encoderAwarenessQuery),
|
|
384
|
+
this
|
|
385
|
+
);
|
|
386
|
+
const encoderAwarenessState = lib0_encoding.createEncoder();
|
|
387
|
+
lib0_encoding.writeVarUint(encoderAwarenessState, messageAwareness);
|
|
388
|
+
lib0_encoding.writeVarUint8Array(
|
|
389
|
+
encoderAwarenessState,
|
|
390
|
+
y_protocols_awareness.encodeAwarenessUpdate(this.awareness, [
|
|
391
|
+
this.doc.clientID
|
|
392
|
+
])
|
|
393
|
+
);
|
|
394
|
+
lib0_broadcastchannel.publish(
|
|
395
|
+
this.bcChannel,
|
|
396
|
+
lib0_encoding.toUint8Array(encoderAwarenessState),
|
|
397
|
+
this
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
disconnectBc() {
|
|
401
|
+
const encoder = lib0_encoding.createEncoder();
|
|
402
|
+
lib0_encoding.writeVarUint(encoder, messageAwareness);
|
|
403
|
+
lib0_encoding.writeVarUint8Array(
|
|
404
|
+
encoder,
|
|
405
|
+
y_protocols_awareness.encodeAwarenessUpdate(
|
|
406
|
+
this.awareness,
|
|
407
|
+
[this.doc.clientID],
|
|
408
|
+
/* @__PURE__ */ new Map()
|
|
409
|
+
)
|
|
410
|
+
);
|
|
411
|
+
broadcastMessage(this, lib0_encoding.toUint8Array(encoder));
|
|
412
|
+
if (this.bcconnected) {
|
|
413
|
+
lib0_broadcastchannel.unsubscribe(this.bcChannel, this._bcSubscriber);
|
|
414
|
+
this.bcconnected = false;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
disconnect() {
|
|
418
|
+
this.shouldConnect = false;
|
|
419
|
+
this.disconnectBc();
|
|
420
|
+
if (this.ws !== null) this.ws.close();
|
|
421
|
+
}
|
|
422
|
+
connect() {
|
|
423
|
+
this.shouldConnect = true;
|
|
424
|
+
if (!this.wsconnected && this.ws === null) {
|
|
425
|
+
setupWS(this);
|
|
426
|
+
this.connectBc();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
function assertType(value, label, type) {
|
|
431
|
+
if (typeof value !== type)
|
|
432
|
+
throw new Error(
|
|
433
|
+
`Invalid "${label}" parameter provided to YProvider. Expected: ${type}, received: ${value}`
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
var YProvider = class extends WebsocketProvider {
|
|
437
|
+
id;
|
|
438
|
+
#params;
|
|
439
|
+
constructor(host, room, doc, options = {}) {
|
|
440
|
+
assertType(host, "host", "string");
|
|
441
|
+
assertType(room, "room", "string");
|
|
442
|
+
host = host.replace(/^(http|https|ws|wss):\/\//, "");
|
|
443
|
+
if (host.endsWith("/")) host = host.slice(0, -1);
|
|
444
|
+
const serverUrl = `${options.protocol || (host.startsWith("localhost:") || host.startsWith("127.0.0.1:") || host.startsWith("192.168.") || host.startsWith("10.") || (host.startsWith("172.") && host.split(".")[1] >= "16" && host.split(".")[1] <= "31") ? "ws" : "wss")}://${host}${options.prefix || `/parties/${options.party || "main"}`}`;
|
|
445
|
+
const id = options.connectionId ?? (0, nanoid.nanoid)(10);
|
|
446
|
+
const { params, connect = true, ...rest } = options;
|
|
447
|
+
const baseOptions = {
|
|
448
|
+
...rest,
|
|
449
|
+
isPrefixedUrl: !!options.prefix,
|
|
450
|
+
connect: false
|
|
451
|
+
};
|
|
452
|
+
super(serverUrl, room, doc ?? new yjs.Doc(), baseOptions);
|
|
453
|
+
this.id = id;
|
|
454
|
+
this.#params = params;
|
|
455
|
+
if (connect) this.connect();
|
|
456
|
+
}
|
|
457
|
+
async connect() {
|
|
458
|
+
try {
|
|
459
|
+
const nextParams =
|
|
460
|
+
typeof this.#params === "function"
|
|
461
|
+
? await this.#params()
|
|
462
|
+
: this.#params;
|
|
463
|
+
const urlParams = new URLSearchParams([["_pk", this.id]]);
|
|
464
|
+
if (nextParams) {
|
|
465
|
+
for (const [key, value] of Object.entries(nextParams))
|
|
466
|
+
if (value !== null && value !== void 0) urlParams.append(key, value);
|
|
467
|
+
}
|
|
468
|
+
const nextUrl = new URL(this.url);
|
|
469
|
+
nextUrl.search = urlParams.toString();
|
|
470
|
+
this.url = nextUrl.toString();
|
|
471
|
+
super.connect();
|
|
472
|
+
} catch (err) {
|
|
473
|
+
console.error("Failed to open connecton to PartyServer", err);
|
|
474
|
+
throw err;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
sendMessage(message) {
|
|
478
|
+
this.ws?.send(`__YPS:${message}`);
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
//#endregion
|
|
483
|
+
exports.WebsocketProvider = WebsocketProvider;
|
|
484
|
+
exports.default = YProvider;
|
|
485
|
+
exports.messageAuth = messageAuth;
|
|
486
|
+
exports.messageAwareness = messageAwareness;
|
|
487
|
+
exports.messageQueryAwareness = messageQueryAwareness;
|
|
488
|
+
exports.messageSync = messageSync;
|
|
489
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["syncProtocol","awarenessProtocol","decoding","encoding","time","math","Observable","url","YDoc","#params"],"sources":["../../src/provider/index.ts"],"sourcesContent":["import * as bc from \"lib0/broadcastchannel\";\nimport * as decoding from \"lib0/decoding\";\nimport * as encoding from \"lib0/encoding\";\nimport * as math from \"lib0/math\";\nimport { Observable } from \"lib0/observable\";\nimport * as time from \"lib0/time\";\nimport * as url from \"lib0/url\";\nimport { nanoid } from \"nanoid\";\nimport * as authProtocol from \"y-protocols/auth\";\nimport * as awarenessProtocol from \"y-protocols/awareness\";\nimport * as syncProtocol from \"y-protocols/sync\";\nimport { Doc as YDoc } from \"yjs\";\n\nexport const messageSync = 0;\nexport const messageQueryAwareness = 3;\nexport const messageAwareness = 1;\nexport const messageAuth = 2;\n\n// Disable BroadcastChannel by default in Cloudflare Workers / Node\nconst DEFAULT_DISABLE_BC = typeof window === \"undefined\";\n\nconst messageHandlers: Array<\n (\n encoder: encoding.Encoder,\n decoder: decoding.Decoder,\n provider: WebsocketProvider,\n emitSynced: boolean,\n messageType: number\n ) => void\n> = [];\n\nmessageHandlers[messageSync] = (\n encoder,\n decoder,\n provider,\n emitSynced,\n _messageType\n) => {\n encoding.writeVarUint(encoder, messageSync);\n const syncMessageType = syncProtocol.readSyncMessage(\n decoder,\n encoder,\n provider.doc,\n provider\n );\n if (\n emitSynced &&\n syncMessageType === syncProtocol.messageYjsSyncStep2 &&\n !provider.synced\n ) {\n provider.synced = true;\n }\n};\n\nmessageHandlers[messageQueryAwareness] = (\n encoder,\n _decoder,\n provider,\n _emitSynced,\n _messageType\n) => {\n encoding.writeVarUint(encoder, messageAwareness);\n encoding.writeVarUint8Array(\n encoder,\n awarenessProtocol.encodeAwarenessUpdate(\n provider.awareness,\n Array.from(provider.awareness.getStates().keys())\n )\n );\n};\n\nmessageHandlers[messageAwareness] = (\n _encoder,\n decoder,\n provider,\n _emitSynced,\n _messageType\n) => {\n awarenessProtocol.applyAwarenessUpdate(\n provider.awareness,\n decoding.readVarUint8Array(decoder),\n provider\n );\n};\n\nmessageHandlers[messageAuth] = (\n _encoder,\n decoder,\n provider,\n _emitSynced,\n _messageType\n) => {\n authProtocol.readAuthMessage(decoder, provider.doc, (_ydoc, reason) =>\n permissionDeniedHandler(provider, reason)\n );\n};\n\nfunction permissionDeniedHandler(provider: WebsocketProvider, reason: string) {\n console.warn(`Permission denied to access ${provider.url}.\\n${reason}`);\n}\n\nfunction readMessage(\n provider: WebsocketProvider,\n buf: Uint8Array,\n emitSynced: boolean\n): encoding.Encoder {\n const decoder = decoding.createDecoder(buf);\n const encoder = encoding.createEncoder();\n const messageType = decoding.readVarUint(decoder);\n const messageHandler = provider.messageHandlers[messageType];\n if (/** @type {any} */ messageHandler) {\n messageHandler(encoder, decoder, provider, emitSynced, messageType);\n } else {\n console.error(\"Unable to compute message\");\n }\n return encoder;\n}\n\nfunction setupWS(provider: WebsocketProvider) {\n if (provider.shouldConnect && provider.ws === null) {\n if (!provider._WS) {\n throw new Error(\n \"No WebSocket implementation available, did you forget to pass options.WebSocketPolyfill?\"\n );\n }\n const websocket = new provider._WS(provider.url);\n websocket.binaryType = \"arraybuffer\";\n provider.ws = websocket;\n provider.wsconnecting = true;\n provider.wsconnected = false;\n provider.synced = false;\n\n websocket.addEventListener(\"message\", (event) => {\n if (typeof event.data === \"string\") {\n // Handle custom messages with __YPS: prefix\n if (event.data.startsWith(\"__YPS:\")) {\n const customMessage = event.data.slice(6); // Remove __YPS: prefix\n provider.emit(\"custom-message\", [customMessage]);\n }\n return;\n }\n provider.wsLastMessageReceived = time.getUnixTime();\n const encoder = readMessage(provider, new Uint8Array(event.data), true);\n if (encoding.length(encoder) > 1) {\n websocket.send(encoding.toUint8Array(encoder));\n }\n });\n websocket.addEventListener(\"error\", (event) => {\n provider.emit(\"connection-error\", [event, provider]);\n });\n websocket.addEventListener(\"close\", (event) => {\n provider.emit(\"connection-close\", [event, provider]);\n provider.ws = null;\n provider.wsconnecting = false;\n if (provider.wsconnected) {\n provider.wsconnected = false;\n provider.synced = false;\n // update awareness (all users except local left)\n const removedClients = Array.from(\n provider.awareness.getStates().keys()\n ).filter((client) => client !== provider.doc.clientID);\n awarenessProtocol.removeAwarenessStates(\n provider.awareness,\n removedClients,\n provider\n );\n // Clear stale meta for remote clients so their awareness\n // updates are accepted on reconnect (clock check starts fresh)\n for (const clientID of removedClients) {\n provider.awareness.meta.delete(clientID);\n }\n provider.emit(\"status\", [\n {\n status: \"disconnected\"\n }\n ]);\n } else {\n provider.wsUnsuccessfulReconnects++;\n }\n // Start with no reconnect timeout and increase timeout by\n // using exponential backoff starting with 100ms\n setTimeout(\n setupWS,\n math.min(\n math.pow(2, provider.wsUnsuccessfulReconnects) * 100,\n provider.maxBackoffTime\n ),\n provider\n );\n });\n websocket.addEventListener(\"open\", () => {\n provider.wsLastMessageReceived = time.getUnixTime();\n provider.wsconnecting = false;\n provider.wsconnected = true;\n provider.wsUnsuccessfulReconnects = 0;\n provider.emit(\"status\", [\n {\n status: \"connected\"\n }\n ]);\n // always send sync step 1 when connected\n const encoder = encoding.createEncoder();\n encoding.writeVarUint(encoder, messageSync);\n syncProtocol.writeSyncStep1(encoder, provider.doc);\n websocket.send(encoding.toUint8Array(encoder));\n // broadcast local awareness state\n if (provider.awareness.getLocalState() !== null) {\n // Re-set local state to bump the awareness clock, ensuring\n // remote clients accept the update even if they have stale meta\n provider.awareness.setLocalState(provider.awareness.getLocalState());\n const encoderAwarenessState = encoding.createEncoder();\n encoding.writeVarUint(encoderAwarenessState, messageAwareness);\n encoding.writeVarUint8Array(\n encoderAwarenessState,\n awarenessProtocol.encodeAwarenessUpdate(provider.awareness, [\n provider.doc.clientID\n ])\n );\n websocket.send(encoding.toUint8Array(encoderAwarenessState));\n }\n });\n provider.emit(\"status\", [\n {\n status: \"connecting\"\n }\n ]);\n }\n}\n\nfunction broadcastMessage(provider: WebsocketProvider, buf: Uint8Array) {\n const ws = provider.ws;\n if (provider.wsconnected && ws && ws.readyState === ws.OPEN) {\n ws.send(buf);\n }\n if (provider.bcconnected) {\n bc.publish(provider.bcChannel, buf, provider);\n }\n}\n\ntype AwarenessUpdate = {\n added: number[];\n updated: number[];\n removed: number[];\n};\n\nconst DefaultWebSocket = typeof WebSocket === \"undefined\" ? null : WebSocket;\n\n/**\n * Websocket Provider for Yjs. Creates a websocket connection to sync the shared document.\n * The document name is attached to the provided url. I.e. the following example\n * creates a websocket connection to http://localhost:1234/my-document-name\n *\n * @example\n * import * as Y from 'yjs'\n * import { WebsocketProvider } from 'y-websocket'\n * const doc = new Y.Doc()\n * const provider = new WebsocketProvider('http://localhost:1234', 'my-document-name', doc)\n *\n * @extends {Observable<string>}\n */\nexport class WebsocketProvider extends Observable<string> {\n maxBackoffTime: number;\n bcChannel: string;\n url: string;\n roomname: string;\n doc: YDoc;\n _WS: typeof WebSocket;\n awareness: awarenessProtocol.Awareness;\n wsconnected: boolean;\n wsconnecting: boolean;\n bcconnected: boolean;\n disableBc: boolean;\n wsUnsuccessfulReconnects: number;\n messageHandlers: typeof messageHandlers;\n _synced: boolean;\n ws: WebSocket | null;\n wsLastMessageReceived: number;\n shouldConnect: boolean; // Whether to connect to other peers or not\n _resyncInterval: ReturnType<typeof setInterval> | number;\n _bcSubscriber: (message: Uint8Array, origin: unknown) => void;\n _updateHandler: (update: Uint8Array, origin: unknown) => void;\n _awarenessUpdateHandler: (update: AwarenessUpdate, origin: unknown) => void;\n _unloadHandler: () => void;\n\n constructor(\n serverUrl: string,\n roomname: string,\n doc: YDoc,\n {\n connect = true,\n awareness = new awarenessProtocol.Awareness(doc),\n params = {},\n isPrefixedUrl = false,\n WebSocketPolyfill = DefaultWebSocket, // Optionally provide a WebSocket polyfill\n resyncInterval = -1, // Request server state every `resyncInterval` milliseconds\n maxBackoffTime = 2500, // Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential backoff)\n disableBc = DEFAULT_DISABLE_BC // Disable cross-tab BroadcastChannel communication\n }: {\n connect?: boolean;\n awareness?: awarenessProtocol.Awareness;\n params?: { [s: string]: string };\n isPrefixedUrl?: boolean;\n WebSocketPolyfill?: typeof WebSocket | null;\n resyncInterval?: number;\n maxBackoffTime?: number;\n disableBc?: boolean;\n } = {}\n ) {\n super();\n // ensure that url is always ends with /\n while (serverUrl[serverUrl.length - 1] === \"/\") {\n serverUrl = serverUrl.slice(0, serverUrl.length - 1);\n }\n const encodedParams = url.encodeQueryParams(params);\n this.maxBackoffTime = maxBackoffTime;\n this.bcChannel = `${serverUrl}/${roomname}`;\n this.url = isPrefixedUrl\n ? serverUrl\n : `${serverUrl}/${roomname}${encodedParams.length === 0 ? \"\" : `?${encodedParams}`}`;\n this.roomname = roomname;\n this.doc = doc;\n this._WS = WebSocketPolyfill!;\n this.awareness = awareness;\n this.wsconnected = false;\n this.wsconnecting = false;\n this.bcconnected = false;\n this.disableBc = disableBc;\n this.wsUnsuccessfulReconnects = 0;\n this.messageHandlers = messageHandlers.slice();\n\n this._synced = false;\n\n this.ws = null;\n this.wsLastMessageReceived = 0;\n\n this.shouldConnect = connect;\n\n this._resyncInterval = 0;\n if (resyncInterval > 0) {\n this._resyncInterval = /** @type {any} */ setInterval(() => {\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n // resend sync step 1\n const encoder = encoding.createEncoder();\n encoding.writeVarUint(encoder, messageSync);\n syncProtocol.writeSyncStep1(encoder, doc);\n this.ws.send(encoding.toUint8Array(encoder));\n }\n }, resyncInterval);\n }\n\n this._bcSubscriber = (data: Uint8Array, origin: unknown) => {\n if (origin !== this) {\n const encoder = readMessage(this, new Uint8Array(data), false);\n if (encoding.length(encoder) > 1) {\n bc.publish(this.bcChannel, encoding.toUint8Array(encoder), this);\n }\n }\n };\n /**\n * Listens to Yjs updates and sends them to remote peers (ws and broadcastchannel)\n */\n this._updateHandler = (update: Uint8Array, origin: unknown) => {\n if (origin !== this) {\n const encoder = encoding.createEncoder();\n encoding.writeVarUint(encoder, messageSync);\n syncProtocol.writeUpdate(encoder, update);\n broadcastMessage(this, encoding.toUint8Array(encoder));\n }\n };\n this.doc.on(\"update\", this._updateHandler);\n\n this._awarenessUpdateHandler = (\n { added, updated, removed }: AwarenessUpdate,\n _origin: unknown\n ) => {\n const changedClients = added.concat(updated).concat(removed);\n const encoder = encoding.createEncoder();\n encoding.writeVarUint(encoder, messageAwareness);\n encoding.writeVarUint8Array(\n encoder,\n awarenessProtocol.encodeAwarenessUpdate(awareness, changedClients)\n );\n broadcastMessage(this, encoding.toUint8Array(encoder));\n };\n this._unloadHandler = () => {\n awarenessProtocol.removeAwarenessStates(\n this.awareness,\n [doc.clientID],\n \"window unload\"\n );\n };\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"unload\", this._unloadHandler);\n } else if (\n typeof process !== \"undefined\" &&\n typeof process.on === \"function\"\n ) {\n process.on(\"exit\", this._unloadHandler);\n }\n // Listen on 'change' (not 'update') so that clock-only awareness\n // renewals (the 15-second heartbeat) do NOT produce network traffic.\n // Only actual state changes (cursor moved, name changed, etc.) are sent.\n // This allows Durable Objects to hibernate when sessions are idle.\n awareness.on(\"change\", this._awarenessUpdateHandler);\n\n // Disable the awareness protocol's built-in check interval.\n // It renews the local clock every 15s (causing wire traffic that defeats\n // DO hibernation) and removes remote peers after 30s of inactivity.\n // We handle peer cleanup via WebSocket close events instead.\n clearInterval(\n (\n awareness as unknown as {\n _checkInterval: ReturnType<typeof setInterval>;\n }\n )._checkInterval\n );\n if (connect) {\n this.connect();\n }\n }\n\n /**\n * @type {boolean}\n */\n get synced() {\n return this._synced;\n }\n\n set synced(state) {\n if (this._synced !== state) {\n this._synced = state;\n this.emit(\"synced\", [state]);\n this.emit(\"sync\", [state]);\n }\n }\n\n destroy() {\n if (this._resyncInterval !== 0) {\n clearInterval(this._resyncInterval);\n }\n this.disconnect();\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"unload\", this._unloadHandler);\n } else if (\n typeof process !== \"undefined\" &&\n typeof process.off === \"function\"\n ) {\n process.off(\"exit\", this._unloadHandler);\n }\n this.awareness.off(\"change\", this._awarenessUpdateHandler);\n this.doc.off(\"update\", this._updateHandler);\n super.destroy();\n }\n\n connectBc() {\n if (this.disableBc) {\n return;\n }\n if (!this.bcconnected) {\n bc.subscribe(this.bcChannel, this._bcSubscriber);\n this.bcconnected = true;\n }\n // send sync step1 to bc\n // write sync step 1\n const encoderSync = encoding.createEncoder();\n encoding.writeVarUint(encoderSync, messageSync);\n syncProtocol.writeSyncStep1(encoderSync, this.doc);\n bc.publish(this.bcChannel, encoding.toUint8Array(encoderSync), this);\n // broadcast local state\n const encoderState = encoding.createEncoder();\n encoding.writeVarUint(encoderState, messageSync);\n syncProtocol.writeSyncStep2(encoderState, this.doc);\n bc.publish(this.bcChannel, encoding.toUint8Array(encoderState), this);\n // write queryAwareness\n const encoderAwarenessQuery = encoding.createEncoder();\n encoding.writeVarUint(encoderAwarenessQuery, messageQueryAwareness);\n bc.publish(\n this.bcChannel,\n encoding.toUint8Array(encoderAwarenessQuery),\n this\n );\n // broadcast local awareness state\n const encoderAwarenessState = encoding.createEncoder();\n encoding.writeVarUint(encoderAwarenessState, messageAwareness);\n encoding.writeVarUint8Array(\n encoderAwarenessState,\n awarenessProtocol.encodeAwarenessUpdate(this.awareness, [\n this.doc.clientID\n ])\n );\n bc.publish(\n this.bcChannel,\n encoding.toUint8Array(encoderAwarenessState),\n this\n );\n }\n\n disconnectBc() {\n // broadcast message with local awareness state set to null (indicating disconnect)\n const encoder = encoding.createEncoder();\n encoding.writeVarUint(encoder, messageAwareness);\n encoding.writeVarUint8Array(\n encoder,\n awarenessProtocol.encodeAwarenessUpdate(\n this.awareness,\n [this.doc.clientID],\n new Map()\n )\n );\n broadcastMessage(this, encoding.toUint8Array(encoder));\n if (this.bcconnected) {\n bc.unsubscribe(this.bcChannel, this._bcSubscriber);\n this.bcconnected = false;\n }\n }\n\n disconnect() {\n this.shouldConnect = false;\n this.disconnectBc();\n if (this.ws !== null) {\n this.ws.close();\n }\n }\n\n connect() {\n this.shouldConnect = true;\n if (!this.wsconnected && this.ws === null) {\n setupWS(this);\n this.connectBc();\n }\n }\n}\n\nfunction assertType(value: unknown, label: string, type: string) {\n if (typeof value !== type) {\n throw new Error(\n `Invalid \"${label}\" parameter provided to YProvider. Expected: ${type}, received: ${value as string}`\n );\n }\n}\n\ntype Params = Record<string, string | null | undefined>;\ntype ParamsProvider = Params | (() => Params | Promise<Params>);\ntype BaseProviderOptions = ConstructorParameters<typeof WebsocketProvider>[3];\n\ntype YProviderOptions = Omit<NonNullable<BaseProviderOptions>, \"params\"> & {\n connectionId?: string;\n party?: string;\n prefix?: string;\n params?: ParamsProvider;\n protocol?: \"ws\" | \"wss\";\n};\n\nexport default class YProvider extends WebsocketProvider {\n id: string;\n #params?: ParamsProvider;\n\n constructor(\n host: string,\n room: string,\n doc?: YDoc,\n options: YProviderOptions = {}\n ) {\n assertType(host, \"host\", \"string\");\n assertType(room, \"room\", \"string\");\n\n // strip the protocol from the beginning of `host` if any\n host = host.replace(/^(http|https|ws|wss):\\/\\//, \"\");\n\n // strip trailing slash from host if any\n if (host.endsWith(\"/\")) {\n host = host.slice(0, -1);\n }\n\n const serverUrl = `${\n options.protocol ||\n (host.startsWith(\"localhost:\") ||\n host.startsWith(\"127.0.0.1:\") ||\n host.startsWith(\"192.168.\") ||\n host.startsWith(\"10.\") ||\n (host.startsWith(\"172.\") &&\n host.split(\".\")[1] >= \"16\" &&\n host.split(\".\")[1] <= \"31\")\n ? \"ws\"\n : \"wss\")\n }://${host}${options.prefix || `/parties/${options.party || \"main\"}`}`;\n\n // use provided id, or generate a random one\n const id = options.connectionId ?? nanoid(10);\n\n // don't pass params to WebsocketProvider, we override them in connect()\n const { params, connect = true, ...rest } = options;\n\n // don't connect until we've updated the url parameters\n const baseOptions = {\n ...rest,\n isPrefixedUrl: !!options.prefix,\n connect: false\n };\n\n super(serverUrl, room, doc ?? new YDoc(), baseOptions);\n\n this.id = id;\n this.#params = params;\n\n if (connect) {\n void this.connect();\n }\n }\n\n async connect() {\n try {\n // get updated url parameters\n const nextParams =\n typeof this.#params === \"function\"\n ? await this.#params()\n : this.#params;\n // override current url parameters before connecting\n const urlParams = new URLSearchParams([[\"_pk\", this.id]]);\n if (nextParams) {\n for (const [key, value] of Object.entries(nextParams)) {\n // filter out null/undefined values\n if (value !== null && value !== undefined) {\n urlParams.append(key, value);\n }\n }\n }\n\n const nextUrl = new URL(this.url);\n nextUrl.search = urlParams.toString();\n this.url = nextUrl.toString();\n\n // finally, connect\n super.connect();\n } catch (err) {\n console.error(\"Failed to open connecton to PartyServer\", err);\n throw err;\n }\n }\n\n sendMessage(message: string) {\n this.ws?.send(`__YPS:${message}`);\n }\n}\n"],"mappings":"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"}
|