@mml-io/networked-dom-document 0.20.0 → 0.21.1
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/build/NetworkedDOM.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare class NetworkedDOM {
|
|
|
38
38
|
addNetworkedDOMConnection(networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection): void;
|
|
39
39
|
removeNetworkedDOMConnection(networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection): void;
|
|
40
40
|
connectUsers(networkedDOMConnection: NetworkedDOMV01Connection | NetworkedDOMV02Connection, addedExternalUserIds: Set<number>): Map<number, number>;
|
|
41
|
-
announceConnectedUsers(userIds:
|
|
41
|
+
announceConnectedUsers(userIds: Map<number, string | null>): void;
|
|
42
42
|
disconnectUsers(networkedDOMConnection: NetworkedDOMV02Connection, removedExternalToInternalUserIds: Map<number, number>): Array<NetworkedDOMV02Diff>;
|
|
43
43
|
private defaultLogCallback;
|
|
44
44
|
private sendPings;
|
|
@@ -5,6 +5,7 @@ export declare class NetworkedDOMV02Connection {
|
|
|
5
5
|
private websocketListener;
|
|
6
6
|
externalIdToInternalId: Map<number, number>;
|
|
7
7
|
internalIdToExternalId: Map<number, number>;
|
|
8
|
+
internalIdToToken: Map<number, string | null>;
|
|
8
9
|
private batchMode;
|
|
9
10
|
private batchMessages;
|
|
10
11
|
externalConnectionIds: Set<number>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NetworkedDOMV01Connection } from "./NetworkedDOMV01Connection";
|
|
2
2
|
import { NetworkedDOMV02Connection } from "./NetworkedDOMV02Connection";
|
|
3
|
-
export declare const SupportedWebsocketSubProtocolsPreferenceOrder: readonly ["networked-dom-v0.2", "networked-dom-v0.1"];
|
|
3
|
+
export declare const SupportedWebsocketSubProtocolsPreferenceOrder: readonly ["networked-dom-v0.2.1", "networked-dom-v0.2", "networked-dom-v0.1"];
|
|
4
4
|
export declare const defaultWebsocketSubProtocol = "networked-dom-v0.1";
|
|
5
5
|
export declare function createNetworkedDOMConnectionForWebsocket(webSocket: WebSocket): NetworkedDOMV01Connection | NetworkedDOMV02Connection | null;
|
package/build/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/createNetworkedDOMConnectionForWebsocket.ts
|
|
2
2
|
import {
|
|
3
|
+
isNetworkedDOMProtocolSubProtocol_v0_2 as isNetworkedDOMProtocolSubProtocol_v0_22,
|
|
3
4
|
networkedDOMProtocolSubProtocol_v0_1,
|
|
4
|
-
|
|
5
|
+
networkedDOMProtocolSubProtocol_v0_2_SubVersionsList
|
|
5
6
|
} from "@mml-io/networked-dom-protocol";
|
|
6
7
|
|
|
7
8
|
// src/NetworkedDOMV01Connection.ts
|
|
@@ -57,7 +58,9 @@ var NetworkedDOMV01Connection = class {
|
|
|
57
58
|
const internalConnectionIds = this.networkedDOM.connectUsers(this, /* @__PURE__ */ new Set([1]));
|
|
58
59
|
this.internalConnectionId = internalConnectionIds.entries().next().value[0];
|
|
59
60
|
this.internalIdToExternalId.set(this.internalConnectionId, 1);
|
|
60
|
-
this.networkedDOM.announceConnectedUsers(
|
|
61
|
+
this.networkedDOM.announceConnectedUsers(
|
|
62
|
+
/* @__PURE__ */ new Map([[this.internalConnectionId, null]])
|
|
63
|
+
);
|
|
61
64
|
}
|
|
62
65
|
stringifyAndSendSingleMessage(message) {
|
|
63
66
|
this.webSocket.send("[" + JSON.stringify(message) + "]");
|
|
@@ -77,21 +80,31 @@ import {
|
|
|
77
80
|
decodeClientMessages,
|
|
78
81
|
encodeBatchEnd,
|
|
79
82
|
encodeBatchStart,
|
|
80
|
-
encodeServerMessage
|
|
83
|
+
encodeServerMessage,
|
|
84
|
+
getNetworkedDOMProtocolSubProtocol_v0_2SubversionOrThrow,
|
|
85
|
+
isNetworkedDOMProtocolSubProtocol_v0_2
|
|
81
86
|
} from "@mml-io/networked-dom-protocol";
|
|
82
87
|
var NetworkedDOMV02Connection = class {
|
|
83
88
|
constructor(webSocket) {
|
|
84
89
|
this.webSocket = webSocket;
|
|
85
90
|
this.externalIdToInternalId = /* @__PURE__ */ new Map();
|
|
86
91
|
this.internalIdToExternalId = /* @__PURE__ */ new Map();
|
|
92
|
+
this.internalIdToToken = /* @__PURE__ */ new Map();
|
|
87
93
|
this.batchMode = false;
|
|
88
94
|
this.batchMessages = [];
|
|
89
95
|
this.externalConnectionIds = /* @__PURE__ */ new Set();
|
|
90
96
|
this.networkedDOM = null;
|
|
91
97
|
this.messagesAwaitingNetworkedDOM = [];
|
|
98
|
+
const protocol = webSocket.protocol;
|
|
99
|
+
if (!isNetworkedDOMProtocolSubProtocol_v0_2(protocol)) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
`WebSocket protocol ${protocol} is not a supported networked-dom-v0.2 sub-protocol`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
const protocolSubversion = getNetworkedDOMProtocolSubProtocol_v0_2SubversionOrThrow(protocol);
|
|
92
105
|
this.websocketListener = (messageEvent) => {
|
|
93
106
|
const buffer = new Uint8Array(messageEvent.data);
|
|
94
|
-
const messages = decodeClientMessages(new BufferReader(buffer));
|
|
107
|
+
const messages = decodeClientMessages(new BufferReader(buffer), protocolSubversion);
|
|
95
108
|
for (const parsed of messages) {
|
|
96
109
|
if (this.networkedDOM) {
|
|
97
110
|
this.handleClientMessage(parsed);
|
|
@@ -161,8 +174,12 @@ var NetworkedDOMV02Connection = class {
|
|
|
161
174
|
handleClientMessage(parsed) {
|
|
162
175
|
switch (parsed.type) {
|
|
163
176
|
case "connectUsers": {
|
|
177
|
+
const externalIdsToToken = /* @__PURE__ */ new Map();
|
|
164
178
|
const addedExternalUserIds = /* @__PURE__ */ new Set();
|
|
165
|
-
for (
|
|
179
|
+
for (let i = 0; i < parsed.connectionIds.length; i++) {
|
|
180
|
+
const addingExternalId = parsed.connectionIds[i];
|
|
181
|
+
const correspondingToken = parsed.connectionTokens[i];
|
|
182
|
+
externalIdsToToken.set(addingExternalId, correspondingToken);
|
|
166
183
|
if (!Number.isInteger(addingExternalId) || addingExternalId < 0) {
|
|
167
184
|
this.sendMessage({
|
|
168
185
|
type: "error",
|
|
@@ -195,12 +212,15 @@ var NetworkedDOMV02Connection = class {
|
|
|
195
212
|
this,
|
|
196
213
|
addedExternalUserIds
|
|
197
214
|
);
|
|
198
|
-
const
|
|
215
|
+
const addingInternalIdsWithToken = /* @__PURE__ */ new Map();
|
|
199
216
|
for (const [addingInternalId, addingExternalId] of connectionIdToExternalId) {
|
|
217
|
+
const token = externalIdsToToken.get(addingExternalId) ?? null;
|
|
218
|
+
addingInternalIdsWithToken.set(addingInternalId, token);
|
|
200
219
|
this.externalIdToInternalId.set(addingExternalId, addingInternalId);
|
|
201
220
|
this.internalIdToExternalId.set(addingInternalId, addingExternalId);
|
|
221
|
+
this.internalIdToToken.set(addingInternalId, token);
|
|
202
222
|
}
|
|
203
|
-
this.networkedDOM.announceConnectedUsers(
|
|
223
|
+
this.networkedDOM.announceConnectedUsers(addingInternalIdsWithToken);
|
|
204
224
|
}
|
|
205
225
|
return;
|
|
206
226
|
}
|
|
@@ -246,6 +266,7 @@ var NetworkedDOMV02Connection = class {
|
|
|
246
266
|
this.externalConnectionIds.delete(removingExternalId);
|
|
247
267
|
this.externalIdToInternalId.delete(removingExternalId);
|
|
248
268
|
this.internalIdToExternalId.delete(removingInternalId);
|
|
269
|
+
this.internalIdToToken.delete(removingInternalId);
|
|
249
270
|
}
|
|
250
271
|
} else {
|
|
251
272
|
const removalDiffs = this.networkedDOM.disconnectUsers(
|
|
@@ -301,7 +322,7 @@ var NetworkedDOMV02Connection = class {
|
|
|
301
322
|
|
|
302
323
|
// src/createNetworkedDOMConnectionForWebsocket.ts
|
|
303
324
|
var SupportedWebsocketSubProtocolsPreferenceOrder = [
|
|
304
|
-
|
|
325
|
+
...networkedDOMProtocolSubProtocol_v0_2_SubVersionsList,
|
|
305
326
|
networkedDOMProtocolSubProtocol_v0_1
|
|
306
327
|
];
|
|
307
328
|
var defaultWebsocketSubProtocol = networkedDOMProtocolSubProtocol_v0_1;
|
|
@@ -336,7 +357,7 @@ function createNetworkedDOMConnectionForWebsocket(webSocket) {
|
|
|
336
357
|
webSocket.send(JSON.stringify(warningMessage));
|
|
337
358
|
assumedProtocol = defaultWebsocketSubProtocol;
|
|
338
359
|
}
|
|
339
|
-
const isV02 = assumedProtocol
|
|
360
|
+
const isV02 = isNetworkedDOMProtocolSubProtocol_v0_22(assumedProtocol);
|
|
340
361
|
if (isV02) {
|
|
341
362
|
return new NetworkedDOMV02Connection(webSocket);
|
|
342
363
|
}
|
|
@@ -1030,7 +1051,7 @@ function describeNodeWithChildrenForV01Connection(virtualDOMElement, networkedDO
|
|
|
1030
1051
|
return null;
|
|
1031
1052
|
}
|
|
1032
1053
|
let emittedTagName = virtualDOMElement.tag;
|
|
1033
|
-
if (emittedTagName === "#
|
|
1054
|
+
if (emittedTagName === "#DOCUMENT") {
|
|
1034
1055
|
emittedTagName = "DIV";
|
|
1035
1056
|
}
|
|
1036
1057
|
if (emittedTagName === "#text") {
|
|
@@ -1070,7 +1091,7 @@ function describeNodeWithChildrenForV02Connection(virtualDOMElement, networkedDO
|
|
|
1070
1091
|
return null;
|
|
1071
1092
|
}
|
|
1072
1093
|
let emittedTagName = virtualDOMElement.tag;
|
|
1073
|
-
if (emittedTagName === "#
|
|
1094
|
+
if (emittedTagName === "#DOCUMENT") {
|
|
1074
1095
|
emittedTagName = "DIV";
|
|
1075
1096
|
}
|
|
1076
1097
|
if (emittedTagName === "#text") {
|
|
@@ -1353,6 +1374,12 @@ var NodeManager = class {
|
|
|
1353
1374
|
return [nodeWithSubjectivity, hasSubjectivity];
|
|
1354
1375
|
}
|
|
1355
1376
|
addRemappedNodeId(clientFacingNodeId, internalNodeId) {
|
|
1377
|
+
if (this.internalNodeIdToClientNodeId.has(internalNodeId)) {
|
|
1378
|
+
throw new Error("Node already exists with internal node id " + internalNodeId);
|
|
1379
|
+
}
|
|
1380
|
+
if (this.clientNodeIdToInternalNodeId.has(clientFacingNodeId)) {
|
|
1381
|
+
throw new Error("Node already exists with client id " + clientFacingNodeId);
|
|
1382
|
+
}
|
|
1356
1383
|
this.internalNodeIdToClientNodeId.set(internalNodeId, clientFacingNodeId);
|
|
1357
1384
|
this.clientNodeIdToInternalNodeId.set(clientFacingNodeId, internalNodeId);
|
|
1358
1385
|
this.maximumNodeId = Math.max(this.maximumNodeId, Math.max(clientFacingNodeId, internalNodeId));
|
|
@@ -1366,9 +1393,9 @@ var NodeManager = class {
|
|
|
1366
1393
|
return newId;
|
|
1367
1394
|
}
|
|
1368
1395
|
if (createIfCollided) {
|
|
1369
|
-
if (this.nodeIdToNode.has(nodeId)) {
|
|
1396
|
+
if (this.nodeIdToNode.has(nodeId) || this.clientNodeIdToInternalNodeId.has(nodeId)) {
|
|
1370
1397
|
const newId2 = ++this.maximumNodeId;
|
|
1371
|
-
this.
|
|
1398
|
+
this.addRemappedNodeId(newId2, nodeId);
|
|
1372
1399
|
return newId2;
|
|
1373
1400
|
}
|
|
1374
1401
|
return nodeId;
|
|
@@ -1564,18 +1591,18 @@ var NetworkedDOM = class {
|
|
|
1564
1591
|
}
|
|
1565
1592
|
}
|
|
1566
1593
|
for (const networkedDOMConnection of this.networkedDOMV02Connections) {
|
|
1567
|
-
for (const connectionId of networkedDOMConnection.
|
|
1594
|
+
for (const [connectionId, token] of networkedDOMConnection.internalIdToToken) {
|
|
1568
1595
|
if (connectionId >= this.currentConnectionId) {
|
|
1569
1596
|
this.currentConnectionId = connectionId + 1;
|
|
1570
1597
|
}
|
|
1571
|
-
this.observableDOM.addConnectedUserId(connectionId);
|
|
1598
|
+
this.observableDOM.addConnectedUserId(connectionId, token);
|
|
1572
1599
|
}
|
|
1573
1600
|
}
|
|
1574
1601
|
for (const networkedDOMConnection of this.networkedDOMV01Connections) {
|
|
1575
1602
|
if (networkedDOMConnection.internalConnectionId === null) {
|
|
1576
1603
|
networkedDOMConnection.initAsNewV01Connection();
|
|
1577
1604
|
}
|
|
1578
|
-
this.observableDOM.addConnectedUserId(networkedDOMConnection.internalConnectionId);
|
|
1605
|
+
this.observableDOM.addConnectedUserId(networkedDOMConnection.internalConnectionId, null);
|
|
1579
1606
|
}
|
|
1580
1607
|
for (const networkedDOMConnection of this.networkedDOMV02Connections) {
|
|
1581
1608
|
networkedDOMConnection.handleBufferedMessages();
|
|
@@ -1684,8 +1711,8 @@ var NetworkedDOM = class {
|
|
|
1684
1711
|
networkedDOMConnection.webSocket,
|
|
1685
1712
|
networkedDOMConnection
|
|
1686
1713
|
);
|
|
1687
|
-
for (const connectionId of networkedDOMConnection.
|
|
1688
|
-
this.observableDOM.addConnectedUserId(connectionId);
|
|
1714
|
+
for (const [connectionId, token] of networkedDOMConnection.internalIdToToken) {
|
|
1715
|
+
this.observableDOM.addConnectedUserId(connectionId, token);
|
|
1689
1716
|
}
|
|
1690
1717
|
networkedDOMConnection.sendMessage(
|
|
1691
1718
|
this.getInitialV02Snapshot(networkedDOMConnection, documentVirtualDOMElement)
|
|
@@ -1730,8 +1757,8 @@ var NetworkedDOM = class {
|
|
|
1730
1757
|
}
|
|
1731
1758
|
// Called by the connections after storing the mapping of connected users ids
|
|
1732
1759
|
announceConnectedUsers(userIds) {
|
|
1733
|
-
for (const userId of userIds) {
|
|
1734
|
-
this.observableDOM.addConnectedUserId(userId);
|
|
1760
|
+
for (const [userId, token] of userIds) {
|
|
1761
|
+
this.observableDOM.addConnectedUserId(userId, token);
|
|
1735
1762
|
}
|
|
1736
1763
|
}
|
|
1737
1764
|
disconnectUsers(networkedDOMConnection, removedExternalToInternalUserIds) {
|
|
@@ -1763,6 +1790,7 @@ var NetworkedDOM = class {
|
|
|
1763
1790
|
networkedDOMConnection.externalConnectionIds.delete(removingExternalId);
|
|
1764
1791
|
networkedDOMConnection.externalIdToInternalId.delete(removingExternalId);
|
|
1765
1792
|
networkedDOMConnection.internalIdToExternalId.delete(removingInternalId);
|
|
1793
|
+
networkedDOMConnection.internalIdToToken.delete(removingInternalId);
|
|
1766
1794
|
this.connectionIdToNetworkedDOMConnection.delete(removingInternalId);
|
|
1767
1795
|
}
|
|
1768
1796
|
const removedMessagesByParent = /* @__PURE__ */ new Map();
|
|
@@ -2684,7 +2712,7 @@ var NetworkedDOM = class {
|
|
|
2684
2712
|
tag: staticVirtualDOMElement.tag,
|
|
2685
2713
|
attributes: staticVirtualDOMElement.attributes,
|
|
2686
2714
|
childNodes: staticVirtualDOMElement.childNodes.map(
|
|
2687
|
-
(child) => this.reprojectStaticVirtualDOMElementWithMappings(child)
|
|
2715
|
+
(child) => this.reprojectStaticVirtualDOMElementWithMappings(child, createIfCollided)
|
|
2688
2716
|
),
|
|
2689
2717
|
textContent: staticVirtualDOMElement.textContent
|
|
2690
2718
|
};
|