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.
@@ -4,7 +4,16 @@ import debounce from "lodash.debounce";
4
4
  import { Server } from "partyserver";
5
5
  import * as awarenessProtocol from "y-protocols/awareness";
6
6
  import * as syncProtocol from "y-protocols/sync";
7
- import { Doc, UndoManager, XmlElement, XmlFragment, XmlText, applyUpdate, encodeStateAsUpdate, encodeStateVector } from "yjs";
7
+ import {
8
+ Doc,
9
+ UndoManager,
10
+ XmlElement,
11
+ XmlFragment,
12
+ XmlText,
13
+ applyUpdate,
14
+ encodeStateAsUpdate,
15
+ encodeStateVector
16
+ } from "yjs";
8
17
 
9
18
  //#region src/server/index.ts
10
19
  const snapshotOrigin = Symbol("snapshot-origin");
@@ -13,243 +22,340 @@ const wsReadyStateOpen = 1;
13
22
  const messageSync = 0;
14
23
  const messageAwareness = 1;
15
24
  /**
16
- * Internal key used in connection.setState() to track which awareness
17
- * client IDs are controlled by each connection. This survives hibernation
18
- * because connection state is persisted to WebSocket attachments.
19
- */
25
+ * Internal key used in connection.setState() to track which awareness
26
+ * client IDs are controlled by each connection. This survives hibernation
27
+ * because connection state is persisted to WebSocket attachments.
28
+ */
20
29
  const AWARENESS_IDS_KEY = "__ypsAwarenessIds";
21
30
  function getAwarenessIds(conn) {
22
- try {
23
- return conn.state?.[AWARENESS_IDS_KEY] ?? [];
24
- } catch {
25
- return [];
26
- }
31
+ try {
32
+ return conn.state?.[AWARENESS_IDS_KEY] ?? [];
33
+ } catch {
34
+ return [];
35
+ }
27
36
  }
28
37
  function setAwarenessIds(conn, ids) {
29
- try {
30
- conn.setState((prev) => ({
31
- ...prev,
32
- [AWARENESS_IDS_KEY]: ids
33
- }));
34
- } catch {}
38
+ try {
39
+ conn.setState((prev) => ({
40
+ ...prev,
41
+ [AWARENESS_IDS_KEY]: ids
42
+ }));
43
+ } catch {}
35
44
  }
36
45
  var WSSharedDoc = class extends Doc {
37
- awareness;
38
- constructor() {
39
- super({ gc: true });
40
- this.awareness = new awarenessProtocol.Awareness(this);
41
- this.awareness.setLocalState(null);
42
- clearInterval(this.awareness._checkInterval);
43
- }
46
+ awareness;
47
+ constructor() {
48
+ super({ gc: true });
49
+ this.awareness = new awarenessProtocol.Awareness(this);
50
+ this.awareness.setLocalState(null);
51
+ clearInterval(this.awareness._checkInterval);
52
+ }
44
53
  };
45
54
  const CALLBACK_DEFAULTS = {
46
- debounceWait: 2e3,
47
- debounceMaxWait: 1e4,
48
- timeout: 5e3
55
+ debounceWait: 2e3,
56
+ debounceMaxWait: 1e4,
57
+ timeout: 5e3
49
58
  };
50
- function readSyncMessage(decoder, encoder, doc, transactionOrigin, readOnly = false) {
51
- const messageType = decoding.readVarUint(decoder);
52
- switch (messageType) {
53
- case syncProtocol.messageYjsSyncStep1:
54
- syncProtocol.readSyncStep1(decoder, encoder, doc);
55
- break;
56
- case syncProtocol.messageYjsSyncStep2:
57
- if (!readOnly) syncProtocol.readSyncStep2(decoder, doc, transactionOrigin);
58
- break;
59
- case syncProtocol.messageYjsUpdate:
60
- if (!readOnly) syncProtocol.readUpdate(decoder, doc, transactionOrigin);
61
- break;
62
- default: throw new Error("Unknown message type");
63
- }
64
- return messageType;
59
+ function readSyncMessage(
60
+ decoder,
61
+ encoder,
62
+ doc,
63
+ transactionOrigin,
64
+ readOnly = false
65
+ ) {
66
+ const messageType = decoding.readVarUint(decoder);
67
+ switch (messageType) {
68
+ case syncProtocol.messageYjsSyncStep1:
69
+ syncProtocol.readSyncStep1(decoder, encoder, doc);
70
+ break;
71
+ case syncProtocol.messageYjsSyncStep2:
72
+ if (!readOnly)
73
+ syncProtocol.readSyncStep2(decoder, doc, transactionOrigin);
74
+ break;
75
+ case syncProtocol.messageYjsUpdate:
76
+ if (!readOnly) syncProtocol.readUpdate(decoder, doc, transactionOrigin);
77
+ break;
78
+ default:
79
+ throw new Error("Unknown message type");
80
+ }
81
+ return messageType;
65
82
  }
66
83
  function send(conn, m) {
67
- if (conn.readyState !== void 0 && conn.readyState !== wsReadyStateConnecting && conn.readyState !== wsReadyStateOpen) return;
68
- try {
69
- conn.send(m);
70
- } catch {}
84
+ if (
85
+ conn.readyState !== void 0 &&
86
+ conn.readyState !== wsReadyStateConnecting &&
87
+ conn.readyState !== wsReadyStateOpen
88
+ )
89
+ return;
90
+ try {
91
+ conn.send(m);
92
+ } catch {}
71
93
  }
72
- var YServer = class extends Server {
73
- static callbackOptions = {};
74
- #ParentClass = Object.getPrototypeOf(this).constructor;
75
- document = new WSSharedDoc();
76
- async onLoad() {}
77
- async onSave() {}
78
- /**
79
- * Replaces the document with a different state using Yjs UndoManager key remapping.
80
- *
81
- * @param snapshotUpdate - The snapshot update to replace the document with.
82
- * @param getMetadata (optional) - A function that returns the type of the root for a given key.
83
- */
84
- unstable_replaceDocument(snapshotUpdate, getMetadata = () => "Map") {
85
- try {
86
- const doc = this.document;
87
- const snapshotDoc = new Doc();
88
- applyUpdate(snapshotDoc, snapshotUpdate, snapshotOrigin);
89
- const currentStateVector = encodeStateVector(doc);
90
- const changesSinceSnapshotUpdate = encodeStateAsUpdate(doc, encodeStateVector(snapshotDoc));
91
- const undoManager = new UndoManager([...snapshotDoc.share.keys()].map((key) => {
92
- const type = getMetadata(key);
93
- if (type === "Text") return snapshotDoc.getText(key);
94
- else if (type === "Map") return snapshotDoc.getMap(key);
95
- else if (type === "Array") return snapshotDoc.getArray(key);
96
- else if (type === "XmlText") return snapshotDoc.get(key, XmlText);
97
- else if (type === "XmlElement") return snapshotDoc.get(key, XmlElement);
98
- else if (type === "XmlFragment") return snapshotDoc.get(key, XmlFragment);
99
- throw new Error(`Unknown root type: ${type} for key: ${key}`);
100
- }), { trackedOrigins: new Set([snapshotOrigin]) });
101
- applyUpdate(snapshotDoc, changesSinceSnapshotUpdate, snapshotOrigin);
102
- undoManager.undo();
103
- const documentChangesSinceSnapshotUpdate = encodeStateAsUpdate(snapshotDoc, currentStateVector);
104
- applyUpdate(this.document, documentChangesSinceSnapshotUpdate);
105
- } catch (error) {
106
- throw new Error(`Failed to replace document: ${error instanceof Error ? error.message : "Unknown error"}`);
107
- }
108
- }
109
- async onStart() {
110
- const src = await this.onLoad();
111
- if (src != null) {
112
- const state = encodeStateAsUpdate(src);
113
- applyUpdate(this.document, state);
114
- }
115
- this.document.on("update", (update) => {
116
- const encoder = encoding.createEncoder();
117
- encoding.writeVarUint(encoder, messageSync);
118
- syncProtocol.writeUpdate(encoder, update);
119
- const message = encoding.toUint8Array(encoder);
120
- for (const conn of this.getConnections()) send(conn, message);
121
- });
122
- this.document.awareness.on("update", ({ added, updated, removed }, conn) => {
123
- if (conn !== null) try {
124
- const currentIds = new Set(getAwarenessIds(conn));
125
- for (const clientID of added) currentIds.add(clientID);
126
- for (const clientID of removed) currentIds.delete(clientID);
127
- setAwarenessIds(conn, [...currentIds]);
128
- } catch (_e) {}
129
- else {
130
- const changedClients = added.concat(updated, removed);
131
- const encoder = encoding.createEncoder();
132
- encoding.writeVarUint(encoder, messageAwareness);
133
- encoding.writeVarUint8Array(encoder, awarenessProtocol.encodeAwarenessUpdate(this.document.awareness, changedClients));
134
- const buff = encoding.toUint8Array(encoder);
135
- for (const c of this.getConnections()) send(c, buff);
136
- }
137
- });
138
- this.document.on("update", debounce((_update, _origin, _doc) => {
139
- try {
140
- this.onSave().catch((err) => {
141
- console.error("failed to persist:", err);
142
- });
143
- } catch (err) {
144
- console.error("failed to persist:", err);
145
- }
146
- }, this.#ParentClass.callbackOptions.debounceWait || CALLBACK_DEFAULTS.debounceWait, { maxWait: this.#ParentClass.callbackOptions.debounceMaxWait || CALLBACK_DEFAULTS.debounceMaxWait }));
147
- const syncEncoder = encoding.createEncoder();
148
- encoding.writeVarUint(syncEncoder, messageSync);
149
- syncProtocol.writeSyncStep1(syncEncoder, this.document);
150
- const syncMessage = encoding.toUint8Array(syncEncoder);
151
- for (const conn of this.getConnections()) send(conn, syncMessage);
152
- }
153
- isReadOnly(connection) {
154
- return false;
155
- }
156
- /**
157
- * Handle custom string messages from the client.
158
- * Override this method to implement custom message handling.
159
- * @param connection - The connection that sent the message
160
- * @param message - The custom message string (without the __YPS: prefix)
161
- */
162
- onCustomMessage(connection, message) {
163
- console.warn(`Received custom message but onCustomMessage is not implemented in ${this.#ParentClass.name}:`, message);
164
- }
165
- /**
166
- * Send a custom string message to a specific connection.
167
- * @param connection - The connection to send the message to
168
- * @param message - The custom message string to send
169
- */
170
- sendCustomMessage(connection, message) {
171
- if (connection.readyState !== void 0 && connection.readyState !== wsReadyStateConnecting && connection.readyState !== wsReadyStateOpen) return;
172
- try {
173
- connection.send(`__YPS:${message}`);
174
- } catch (e) {
175
- console.warn("Failed to send custom message", e);
176
- }
177
- }
178
- /**
179
- * Broadcast a custom string message to all connected clients.
180
- * @param message - The custom message string to broadcast
181
- * @param excludeConnection - Optional connection to exclude from the broadcast
182
- */
183
- broadcastCustomMessage(message, excludeConnection) {
184
- const formattedMessage = `__YPS:${message}`;
185
- for (const conn of this.getConnections()) {
186
- if (excludeConnection && conn === excludeConnection) continue;
187
- if (conn.readyState !== void 0 && conn.readyState !== wsReadyStateConnecting && conn.readyState !== wsReadyStateOpen) continue;
188
- try {
189
- conn.send(formattedMessage);
190
- } catch (e) {
191
- console.warn("Failed to broadcast custom message", e);
192
- }
193
- }
194
- }
195
- handleMessage(connection, message) {
196
- if (typeof message === "string") {
197
- if (message.startsWith("__YPS:")) {
198
- const customMessage = message.slice(6);
199
- this.onCustomMessage(connection, customMessage);
200
- return;
201
- }
202
- console.warn(`Received non-prefixed string message. Custom messages should be sent using sendMessage() on the provider.`);
203
- return;
204
- }
205
- try {
206
- const encoder = encoding.createEncoder();
207
- const uint8Array = message instanceof Uint8Array ? message : message instanceof ArrayBuffer ? new Uint8Array(message) : new Uint8Array(message.buffer, message.byteOffset, message.byteLength);
208
- const decoder = decoding.createDecoder(uint8Array);
209
- switch (decoding.readVarUint(decoder)) {
210
- case messageSync:
211
- encoding.writeVarUint(encoder, messageSync);
212
- readSyncMessage(decoder, encoder, this.document, connection, this.isReadOnly(connection));
213
- if (encoding.length(encoder) > 1) send(connection, encoding.toUint8Array(encoder));
214
- break;
215
- case messageAwareness: {
216
- const awarenessData = decoding.readVarUint8Array(decoder);
217
- awarenessProtocol.applyAwarenessUpdate(this.document.awareness, awarenessData, connection);
218
- const awarenessEncoder = encoding.createEncoder();
219
- encoding.writeVarUint(awarenessEncoder, messageAwareness);
220
- encoding.writeVarUint8Array(awarenessEncoder, awarenessData);
221
- const awarenessBuff = encoding.toUint8Array(awarenessEncoder);
222
- for (const c of this.getConnections()) send(c, awarenessBuff);
223
- break;
224
- }
225
- }
226
- } catch (err) {
227
- console.error(err);
228
- this.document.emit("error", [err]);
229
- }
230
- }
231
- onMessage(conn, message) {
232
- this.handleMessage(conn, message);
233
- }
234
- onClose(connection, _code, _reason, _wasClean) {
235
- const controlledIds = getAwarenessIds(connection);
236
- if (controlledIds.length > 0) awarenessProtocol.removeAwarenessStates(this.document.awareness, controlledIds, null);
237
- }
238
- onConnect(conn, _ctx) {
239
- const encoder = encoding.createEncoder();
240
- encoding.writeVarUint(encoder, messageSync);
241
- syncProtocol.writeSyncStep1(encoder, this.document);
242
- send(conn, encoding.toUint8Array(encoder));
243
- const awarenessStates = this.document.awareness.getStates();
244
- if (awarenessStates.size > 0) {
245
- const encoder = encoding.createEncoder();
246
- encoding.writeVarUint(encoder, messageAwareness);
247
- encoding.writeVarUint8Array(encoder, awarenessProtocol.encodeAwarenessUpdate(this.document.awareness, Array.from(awarenessStates.keys())));
248
- send(conn, encoding.toUint8Array(encoder));
249
- }
250
- }
251
- };
94
+ function withYjs(Base) {
95
+ class YjsMixin extends Base {
96
+ static callbackOptions = {};
97
+ document = new WSSharedDoc();
98
+ async onLoad() {}
99
+ async onSave() {}
100
+ /**
101
+ * Replaces the document with a different state using Yjs UndoManager key remapping.
102
+ *
103
+ * @param snapshotUpdate - The snapshot update to replace the document with.
104
+ * @param getMetadata (optional) - A function that returns the type of the root for a given key.
105
+ */
106
+ unstable_replaceDocument(snapshotUpdate, getMetadata = () => "Map") {
107
+ try {
108
+ const doc = this.document;
109
+ const snapshotDoc = new Doc();
110
+ applyUpdate(snapshotDoc, snapshotUpdate, snapshotOrigin);
111
+ const currentStateVector = encodeStateVector(doc);
112
+ const changesSinceSnapshotUpdate = encodeStateAsUpdate(
113
+ doc,
114
+ encodeStateVector(snapshotDoc)
115
+ );
116
+ const undoManager = new UndoManager(
117
+ [...snapshotDoc.share.keys()].map((key) => {
118
+ const type = getMetadata(key);
119
+ if (type === "Text") return snapshotDoc.getText(key);
120
+ else if (type === "Map") return snapshotDoc.getMap(key);
121
+ else if (type === "Array") return snapshotDoc.getArray(key);
122
+ else if (type === "XmlText") return snapshotDoc.get(key, XmlText);
123
+ else if (type === "XmlElement")
124
+ return snapshotDoc.get(key, XmlElement);
125
+ else if (type === "XmlFragment")
126
+ return snapshotDoc.get(key, XmlFragment);
127
+ throw new Error(`Unknown root type: ${type} for key: ${key}`);
128
+ }),
129
+ { trackedOrigins: new Set([snapshotOrigin]) }
130
+ );
131
+ applyUpdate(snapshotDoc, changesSinceSnapshotUpdate, snapshotOrigin);
132
+ undoManager.undo();
133
+ const documentChangesSinceSnapshotUpdate = encodeStateAsUpdate(
134
+ snapshotDoc,
135
+ currentStateVector
136
+ );
137
+ applyUpdate(this.document, documentChangesSinceSnapshotUpdate);
138
+ } catch (error) {
139
+ throw new Error(
140
+ `Failed to replace document: ${error instanceof Error ? error.message : "Unknown error"}`
141
+ );
142
+ }
143
+ }
144
+ async onStart() {
145
+ const src = await this.onLoad();
146
+ if (src != null) {
147
+ const state = encodeStateAsUpdate(src);
148
+ applyUpdate(this.document, state);
149
+ }
150
+ this.document.on("update", (update) => {
151
+ const encoder = encoding.createEncoder();
152
+ encoding.writeVarUint(encoder, messageSync);
153
+ syncProtocol.writeUpdate(encoder, update);
154
+ const message = encoding.toUint8Array(encoder);
155
+ for (const conn of this.getConnections()) send(conn, message);
156
+ });
157
+ this.document.awareness.on(
158
+ "update",
159
+ ({ added, updated, removed }, conn) => {
160
+ if (conn !== null)
161
+ try {
162
+ const currentIds = new Set(getAwarenessIds(conn));
163
+ for (const clientID of added) currentIds.add(clientID);
164
+ for (const clientID of removed) currentIds.delete(clientID);
165
+ setAwarenessIds(conn, [...currentIds]);
166
+ } catch (_e) {}
167
+ else {
168
+ const changedClients = added.concat(updated, removed);
169
+ const encoder = encoding.createEncoder();
170
+ encoding.writeVarUint(encoder, messageAwareness);
171
+ encoding.writeVarUint8Array(
172
+ encoder,
173
+ awarenessProtocol.encodeAwarenessUpdate(
174
+ this.document.awareness,
175
+ changedClients
176
+ )
177
+ );
178
+ const buff = encoding.toUint8Array(encoder);
179
+ for (const c of this.getConnections()) send(c, buff);
180
+ }
181
+ }
182
+ );
183
+ const ctor = this.constructor;
184
+ this.document.on(
185
+ "update",
186
+ debounce(
187
+ (_update, _origin, _doc) => {
188
+ try {
189
+ this.onSave().catch((err) => {
190
+ console.error("failed to persist:", err);
191
+ });
192
+ } catch (err) {
193
+ console.error("failed to persist:", err);
194
+ }
195
+ },
196
+ ctor.callbackOptions.debounceWait || CALLBACK_DEFAULTS.debounceWait,
197
+ {
198
+ maxWait:
199
+ ctor.callbackOptions.debounceMaxWait ||
200
+ CALLBACK_DEFAULTS.debounceMaxWait
201
+ }
202
+ )
203
+ );
204
+ const syncEncoder = encoding.createEncoder();
205
+ encoding.writeVarUint(syncEncoder, messageSync);
206
+ syncProtocol.writeSyncStep1(syncEncoder, this.document);
207
+ const syncMessage = encoding.toUint8Array(syncEncoder);
208
+ for (const conn of this.getConnections()) send(conn, syncMessage);
209
+ }
210
+ isReadOnly(connection) {
211
+ return false;
212
+ }
213
+ /**
214
+ * Handle custom string messages from the client.
215
+ * Override this method to implement custom message handling.
216
+ * @param connection - The connection that sent the message
217
+ * @param message - The custom message string (without the __YPS: prefix)
218
+ */
219
+ onCustomMessage(connection, message) {
220
+ console.warn(
221
+ `Received custom message but onCustomMessage is not implemented in ${this.constructor.name}:`,
222
+ message
223
+ );
224
+ }
225
+ /**
226
+ * Send a custom string message to a specific connection.
227
+ * @param connection - The connection to send the message to
228
+ * @param message - The custom message string to send
229
+ */
230
+ sendCustomMessage(connection, message) {
231
+ if (
232
+ connection.readyState !== void 0 &&
233
+ connection.readyState !== wsReadyStateConnecting &&
234
+ connection.readyState !== wsReadyStateOpen
235
+ )
236
+ return;
237
+ try {
238
+ connection.send(`__YPS:${message}`);
239
+ } catch (e) {
240
+ console.warn("Failed to send custom message", e);
241
+ }
242
+ }
243
+ /**
244
+ * Broadcast a custom string message to all connected clients.
245
+ * @param message - The custom message string to broadcast
246
+ * @param excludeConnection - Optional connection to exclude from the broadcast
247
+ */
248
+ broadcastCustomMessage(message, excludeConnection) {
249
+ const formattedMessage = `__YPS:${message}`;
250
+ for (const conn of this.getConnections()) {
251
+ if (excludeConnection && conn === excludeConnection) continue;
252
+ if (
253
+ conn.readyState !== void 0 &&
254
+ conn.readyState !== wsReadyStateConnecting &&
255
+ conn.readyState !== wsReadyStateOpen
256
+ )
257
+ continue;
258
+ try {
259
+ conn.send(formattedMessage);
260
+ } catch (e) {
261
+ console.warn("Failed to broadcast custom message", e);
262
+ }
263
+ }
264
+ }
265
+ handleMessage(connection, message) {
266
+ if (typeof message === "string") {
267
+ if (message.startsWith("__YPS:")) {
268
+ const customMessage = message.slice(6);
269
+ this.onCustomMessage(connection, customMessage);
270
+ return;
271
+ }
272
+ console.warn(
273
+ `Received non-prefixed string message. Custom messages should be sent using sendMessage() on the provider.`
274
+ );
275
+ return;
276
+ }
277
+ try {
278
+ const encoder = encoding.createEncoder();
279
+ const uint8Array =
280
+ message instanceof Uint8Array
281
+ ? message
282
+ : message instanceof ArrayBuffer
283
+ ? new Uint8Array(message)
284
+ : new Uint8Array(
285
+ message.buffer,
286
+ message.byteOffset,
287
+ message.byteLength
288
+ );
289
+ const decoder = decoding.createDecoder(uint8Array);
290
+ switch (decoding.readVarUint(decoder)) {
291
+ case messageSync:
292
+ encoding.writeVarUint(encoder, messageSync);
293
+ readSyncMessage(
294
+ decoder,
295
+ encoder,
296
+ this.document,
297
+ connection,
298
+ this.isReadOnly(connection)
299
+ );
300
+ if (encoding.length(encoder) > 1)
301
+ send(connection, encoding.toUint8Array(encoder));
302
+ break;
303
+ case messageAwareness: {
304
+ const awarenessData = decoding.readVarUint8Array(decoder);
305
+ awarenessProtocol.applyAwarenessUpdate(
306
+ this.document.awareness,
307
+ awarenessData,
308
+ connection
309
+ );
310
+ const awarenessEncoder = encoding.createEncoder();
311
+ encoding.writeVarUint(awarenessEncoder, messageAwareness);
312
+ encoding.writeVarUint8Array(awarenessEncoder, awarenessData);
313
+ const awarenessBuff = encoding.toUint8Array(awarenessEncoder);
314
+ for (const c of this.getConnections()) send(c, awarenessBuff);
315
+ break;
316
+ }
317
+ }
318
+ } catch (err) {
319
+ console.error(err);
320
+ this.document.emit("error", [err]);
321
+ }
322
+ }
323
+ onMessage(conn, message) {
324
+ this.handleMessage(conn, message);
325
+ }
326
+ onClose(connection, _code, _reason, _wasClean) {
327
+ const controlledIds = getAwarenessIds(connection);
328
+ if (controlledIds.length > 0)
329
+ awarenessProtocol.removeAwarenessStates(
330
+ this.document.awareness,
331
+ controlledIds,
332
+ null
333
+ );
334
+ }
335
+ onConnect(conn, _ctx) {
336
+ const encoder = encoding.createEncoder();
337
+ encoding.writeVarUint(encoder, messageSync);
338
+ syncProtocol.writeSyncStep1(encoder, this.document);
339
+ send(conn, encoding.toUint8Array(encoder));
340
+ const awarenessStates = this.document.awareness.getStates();
341
+ if (awarenessStates.size > 0) {
342
+ const encoder = encoding.createEncoder();
343
+ encoding.writeVarUint(encoder, messageAwareness);
344
+ encoding.writeVarUint8Array(
345
+ encoder,
346
+ awarenessProtocol.encodeAwarenessUpdate(
347
+ this.document.awareness,
348
+ Array.from(awarenessStates.keys())
349
+ )
350
+ );
351
+ send(conn, encoding.toUint8Array(encoder));
352
+ }
353
+ }
354
+ }
355
+ return YjsMixin;
356
+ }
357
+ const YServer = withYjs(Server);
252
358
 
253
359
  //#endregion
254
- export { YServer };
255
- //# sourceMappingURL=index.js.map
360
+ export { YServer, withYjs };
361
+ //# sourceMappingURL=index.js.map