@automerge/automerge-repo-network-websocket 1.0.0-alpha.2 → 1.0.0-alpha.3
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/BrowserWebSocketClientAdapter.d.ts +3 -2
- package/dist/BrowserWebSocketClientAdapter.d.ts.map +1 -1
- package/dist/BrowserWebSocketClientAdapter.js +21 -30
- package/dist/NodeWSServerAdapter.d.ts +3 -2
- package/dist/NodeWSServerAdapter.d.ts.map +1 -1
- package/dist/NodeWSServerAdapter.js +19 -38
- package/dist/messages.d.ts +26 -0
- package/dist/messages.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/BrowserWebSocketClientAdapter.ts +33 -55
- package/src/NodeWSServerAdapter.ts +31 -69
- package/src/messages.ts +31 -0
- package/test/Websocket.test.ts +41 -20
- package/dist/message.d.ts +0 -9
- package/dist/message.d.ts.map +0 -1
- package/src/message.ts +0 -10
- /package/dist/{message.js → messages.js} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="ws" />
|
|
2
|
-
import {
|
|
2
|
+
import { NetworkAdapter, PeerId } from "@automerge/automerge-repo";
|
|
3
3
|
import WebSocket from "isomorphic-ws";
|
|
4
|
+
import { FromClientMessage } from "./messages.js";
|
|
4
5
|
declare abstract class WebSocketNetworkAdapter extends NetworkAdapter {
|
|
5
6
|
socket?: WebSocket;
|
|
6
7
|
}
|
|
@@ -11,7 +12,7 @@ export declare class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapt
|
|
|
11
12
|
connect(peerId: PeerId): void;
|
|
12
13
|
join(): void;
|
|
13
14
|
leave(): void;
|
|
14
|
-
|
|
15
|
+
send(message: FromClientMessage): void;
|
|
15
16
|
announceConnection(peerId: PeerId): void;
|
|
16
17
|
receiveMessage(message: Uint8Array): void;
|
|
17
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserWebSocketClientAdapter.d.ts","sourceRoot":"","sources":["../src/BrowserWebSocketClientAdapter.ts"],"names":[],"mappings":";AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"BrowserWebSocketClientAdapter.d.ts","sourceRoot":"","sources":["../src/BrowserWebSocketClientAdapter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,SAAS,MAAM,eAAe,CAAA;AAIrC,OAAO,EACL,iBAAiB,EAGlB,MAAM,eAAe,CAAA;AAMtB,uBAAe,uBAAwB,SAAQ,cAAc;IAC3D,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB;AAED,qBAAa,6BAA8B,SAAQ,uBAAuB;IAGxE,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;IAEvC,GAAG,EAAE,MAAM,CAAA;gBAEC,GAAG,EAAE,MAAM;IAKvB,OAAO,CAAC,MAAM,EAAE,MAAM;IA8BtB,IAAI;IAoBJ,KAAK;IAOL,IAAI,CAAC,OAAO,EAAE,iBAAiB;IAwB/B,kBAAkB,CAAC,MAAM,EAAE,MAAM;IAUjC,cAAc,CAAC,OAAO,EAAE,UAAU;CA6BnC"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { NetworkAdapter
|
|
1
|
+
import { NetworkAdapter } from "@automerge/automerge-repo";
|
|
2
2
|
import * as CBOR from "cbor-x";
|
|
3
3
|
import WebSocket from "isomorphic-ws";
|
|
4
4
|
import debug from "debug";
|
|
5
5
|
import { ProtocolV1 } from "./protocolVersion.js";
|
|
6
|
+
import { isValidMessage } from "@automerge/automerge-repo/dist/network/messages.js";
|
|
6
7
|
const log = debug("WebsocketClient");
|
|
7
8
|
class WebSocketNetworkAdapter extends NetworkAdapter {
|
|
8
9
|
socket;
|
|
9
10
|
}
|
|
10
11
|
export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
11
|
-
// Type trickery required for platform independence,
|
|
12
|
+
// Type trickery required for platform independence,
|
|
12
13
|
// see https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window
|
|
13
14
|
timerId;
|
|
14
15
|
url;
|
|
@@ -44,14 +45,14 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
44
45
|
throw new Error("WTF, get a socket");
|
|
45
46
|
}
|
|
46
47
|
if (this.socket.readyState === WebSocket.OPEN) {
|
|
47
|
-
this.
|
|
48
|
+
this.send(joinMessage(this.peerId));
|
|
48
49
|
}
|
|
49
50
|
else {
|
|
50
51
|
this.socket.addEventListener("open", () => {
|
|
51
52
|
if (!this.socket) {
|
|
52
53
|
throw new Error("WTF, get a socket");
|
|
53
54
|
}
|
|
54
|
-
this.
|
|
55
|
+
this.send(joinMessage(this.peerId));
|
|
55
56
|
}, { once: true });
|
|
56
57
|
}
|
|
57
58
|
}
|
|
@@ -59,31 +60,23 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
59
60
|
if (!this.socket) {
|
|
60
61
|
throw new Error("WTF, get a socket");
|
|
61
62
|
}
|
|
62
|
-
this.
|
|
63
|
+
this.send({ type: "leave", senderId: this.peerId });
|
|
63
64
|
}
|
|
64
|
-
|
|
65
|
-
if (message.byteLength === 0) {
|
|
65
|
+
send(message) {
|
|
66
|
+
if ("data" in message && message.data.byteLength === 0) {
|
|
66
67
|
throw new Error("tried to send a zero-length message");
|
|
67
68
|
}
|
|
68
69
|
if (!this.peerId) {
|
|
69
70
|
throw new Error("Why don't we have a PeerID?");
|
|
70
71
|
}
|
|
71
|
-
const decoded = {
|
|
72
|
-
senderId: this.peerId,
|
|
73
|
-
targetId,
|
|
74
|
-
channelId,
|
|
75
|
-
type: "sync",
|
|
76
|
-
message,
|
|
77
|
-
broadcast,
|
|
78
|
-
};
|
|
79
|
-
const encoded = CBOR.encode(decoded);
|
|
80
|
-
// This incantation deals with websocket sending the whole
|
|
81
|
-
// underlying buffer even if we just have a uint8array view on it
|
|
82
|
-
const arrayBuf = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
|
|
83
72
|
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
84
73
|
throw new Error("Websocket Socket not ready!");
|
|
85
74
|
}
|
|
86
|
-
|
|
75
|
+
const encoded = CBOR.encode(message);
|
|
76
|
+
// This incantation deals with websocket sending the whole
|
|
77
|
+
// underlying buffer even if we just have a uint8array view on it
|
|
78
|
+
const arrayBuf = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
|
|
79
|
+
this.socket?.send(arrayBuf);
|
|
87
80
|
}
|
|
88
81
|
announceConnection(peerId) {
|
|
89
82
|
// return a peer object
|
|
@@ -95,7 +88,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
95
88
|
}
|
|
96
89
|
receiveMessage(message) {
|
|
97
90
|
const decoded = CBOR.decode(new Uint8Array(message));
|
|
98
|
-
const { type, senderId
|
|
91
|
+
const { type, senderId } = decoded;
|
|
99
92
|
const socket = this.socket;
|
|
100
93
|
if (!socket) {
|
|
101
94
|
throw new Error("Missing socket at receiveMessage");
|
|
@@ -105,19 +98,17 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
105
98
|
}
|
|
106
99
|
switch (type) {
|
|
107
100
|
case "peer":
|
|
108
|
-
log(`peer: ${senderId}
|
|
101
|
+
log(`peer: ${senderId}`);
|
|
109
102
|
this.announceConnection(senderId);
|
|
110
103
|
break;
|
|
111
104
|
case "error":
|
|
112
|
-
log(`error: ${decoded.
|
|
105
|
+
log(`error: ${decoded.message}`);
|
|
106
|
+
break;
|
|
113
107
|
default:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
message: new Uint8Array(messageData),
|
|
119
|
-
broadcast,
|
|
120
|
-
});
|
|
108
|
+
if (!isValidMessage(decoded)) {
|
|
109
|
+
throw new Error("Invalid message received");
|
|
110
|
+
}
|
|
111
|
+
this.emit("message", decoded);
|
|
121
112
|
}
|
|
122
113
|
}
|
|
123
114
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="ws" />
|
|
2
2
|
import { WebSocket, type WebSocketServer } from "isomorphic-ws";
|
|
3
|
-
import {
|
|
3
|
+
import { NetworkAdapter, type PeerId } from "@automerge/automerge-repo";
|
|
4
|
+
import { FromServerMessage } from "./messages.js";
|
|
4
5
|
export declare class NodeWSServerAdapter extends NetworkAdapter {
|
|
5
6
|
server: WebSocketServer;
|
|
6
7
|
sockets: {
|
|
@@ -10,7 +11,7 @@ export declare class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
10
11
|
connect(peerId: PeerId): void;
|
|
11
12
|
join(): void;
|
|
12
13
|
leave(): void;
|
|
13
|
-
|
|
14
|
+
send(message: FromServerMessage): void;
|
|
14
15
|
receiveMessage(message: Uint8Array, socket: WebSocket): void;
|
|
15
16
|
}
|
|
16
17
|
//# sourceMappingURL=NodeWSServerAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeWSServerAdapter.d.ts","sourceRoot":"","sources":["../src/NodeWSServerAdapter.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"NodeWSServerAdapter.d.ts","sourceRoot":"","sources":["../src/NodeWSServerAdapter.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAM/D,OAAO,EACL,cAAc,EAEd,KAAK,MAAM,EACZ,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAqB,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEpE,qBAAa,mBAAoB,SAAQ,cAAc;IACrD,MAAM,EAAE,eAAe,CAAA;IACvB,OAAO,EAAE;QAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAK;gBAEjC,MAAM,EAAE,eAAe;IAKnC,OAAO,CAAC,MAAM,EAAE,MAAM;IAmBtB,IAAI;IAIJ,KAAK;IAIL,IAAI,CAAC,OAAO,EAAE,iBAAiB;IAyB/B,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS;CAuDtD"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as CBOR from "cbor-x";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
const log = debug("WebsocketServer");
|
|
4
|
-
import { NetworkAdapter, } from "@automerge/automerge-repo";
|
|
5
4
|
import { ProtocolV1 } from "./protocolVersion.js";
|
|
5
|
+
import { NetworkAdapter, } from "@automerge/automerge-repo";
|
|
6
6
|
export class NodeWSServerAdapter extends NetworkAdapter {
|
|
7
7
|
server;
|
|
8
8
|
sockets = {};
|
|
@@ -31,41 +31,32 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
31
31
|
leave() {
|
|
32
32
|
// throw new Error("The server doesn't join channels.")
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
if (message.byteLength === 0) {
|
|
34
|
+
send(message) {
|
|
35
|
+
if ("data" in message && message.data.byteLength === 0) {
|
|
36
36
|
throw new Error("tried to send a zero-length message");
|
|
37
37
|
}
|
|
38
38
|
const senderId = this.peerId;
|
|
39
39
|
if (!senderId) {
|
|
40
40
|
throw new Error("No peerId set for the websocket server network adapter.");
|
|
41
41
|
}
|
|
42
|
-
if (this.sockets[targetId] === undefined) {
|
|
43
|
-
log(`Tried to send message to disconnected peer: ${targetId}`);
|
|
42
|
+
if (this.sockets[message.targetId] === undefined) {
|
|
43
|
+
log(`Tried to send message to disconnected peer: ${message.targetId}`);
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
const
|
|
47
|
-
senderId,
|
|
48
|
-
targetId,
|
|
49
|
-
channelId,
|
|
50
|
-
type: "sync",
|
|
51
|
-
message,
|
|
52
|
-
broadcast,
|
|
53
|
-
};
|
|
54
|
-
const encoded = CBOR.encode(decoded);
|
|
46
|
+
const encoded = CBOR.encode(message);
|
|
55
47
|
// This incantation deals with websocket sending the whole
|
|
56
48
|
// underlying buffer even if we just have a uint8array view on it
|
|
57
49
|
const arrayBuf = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
|
|
58
|
-
|
|
59
|
-
this.sockets[targetId].send(arrayBuf);
|
|
50
|
+
this.sockets[message.targetId]?.send(arrayBuf);
|
|
60
51
|
}
|
|
61
52
|
receiveMessage(message, socket) {
|
|
62
53
|
const cbor = CBOR.decode(message);
|
|
63
|
-
const { type,
|
|
54
|
+
const { type, senderId } = cbor;
|
|
64
55
|
const myPeerId = this.peerId;
|
|
65
56
|
if (!myPeerId) {
|
|
66
57
|
throw new Error("Missing my peer ID.");
|
|
67
58
|
}
|
|
68
|
-
log(`[${senderId}->${myPeerId}
|
|
59
|
+
log(`[${senderId}->${myPeerId}${"documentId" in cbor ? "@" + cbor.documentId : ""}] ${type} | ${message.byteLength} bytes`);
|
|
69
60
|
switch (type) {
|
|
70
61
|
case "join":
|
|
71
62
|
// Let the rest of the system know that we have a new connection.
|
|
@@ -73,21 +64,24 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
73
64
|
this.sockets[senderId] = socket;
|
|
74
65
|
// In this client-server connection, there's only ever one peer: us!
|
|
75
66
|
// (and we pretend to be joined to every channel)
|
|
76
|
-
const selectedProtocolVersion = selectProtocol(supportedProtocolVersions);
|
|
67
|
+
const selectedProtocolVersion = selectProtocol(cbor.supportedProtocolVersions);
|
|
77
68
|
if (selectedProtocolVersion === null) {
|
|
78
|
-
|
|
69
|
+
this.send({
|
|
79
70
|
type: "error",
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
senderId: this.peerId,
|
|
72
|
+
message: "unsupported protocol version",
|
|
73
|
+
targetId: senderId,
|
|
74
|
+
});
|
|
82
75
|
this.sockets[senderId].close();
|
|
83
76
|
delete this.sockets[senderId];
|
|
84
77
|
}
|
|
85
78
|
else {
|
|
86
|
-
|
|
79
|
+
this.send({
|
|
87
80
|
type: "peer",
|
|
88
81
|
senderId: this.peerId,
|
|
89
82
|
selectedProtocolVersion: ProtocolV1,
|
|
90
|
-
|
|
83
|
+
targetId: senderId,
|
|
84
|
+
});
|
|
91
85
|
}
|
|
92
86
|
break;
|
|
93
87
|
case "leave":
|
|
@@ -96,21 +90,8 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
96
90
|
// TODO: confirm this
|
|
97
91
|
// ?
|
|
98
92
|
break;
|
|
99
|
-
// We accept both "message" and "sync" because a previous version of this
|
|
100
|
-
// codebase sent sync messages in the BrowserWebSocketClientAdapter as
|
|
101
|
-
// type "message" and we want to stay backwards compatible
|
|
102
|
-
case "message":
|
|
103
|
-
case "sync":
|
|
104
|
-
this.emit("message", {
|
|
105
|
-
senderId,
|
|
106
|
-
targetId,
|
|
107
|
-
channelId,
|
|
108
|
-
message: new Uint8Array(data),
|
|
109
|
-
broadcast,
|
|
110
|
-
});
|
|
111
|
-
break;
|
|
112
93
|
default:
|
|
113
|
-
|
|
94
|
+
this.emit("message", cbor);
|
|
114
95
|
break;
|
|
115
96
|
}
|
|
116
97
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Message, type PeerId } from "@automerge/automerge-repo";
|
|
2
|
+
import { ProtocolVersion } from "./protocolVersion.js";
|
|
3
|
+
export type LeaveMessage = {
|
|
4
|
+
type: "leave";
|
|
5
|
+
senderId: PeerId;
|
|
6
|
+
};
|
|
7
|
+
export type JoinMessage = {
|
|
8
|
+
type: "join";
|
|
9
|
+
senderId: PeerId;
|
|
10
|
+
supportedProtocolVersions: ProtocolVersion[];
|
|
11
|
+
};
|
|
12
|
+
export type PeerMessage = {
|
|
13
|
+
type: "peer";
|
|
14
|
+
senderId: PeerId;
|
|
15
|
+
selectedProtocolVersion: ProtocolVersion;
|
|
16
|
+
targetId: PeerId;
|
|
17
|
+
};
|
|
18
|
+
export type ErrorMessage = {
|
|
19
|
+
type: "error";
|
|
20
|
+
senderId: PeerId;
|
|
21
|
+
message: string;
|
|
22
|
+
targetId: PeerId;
|
|
23
|
+
};
|
|
24
|
+
export type FromClientMessage = JoinMessage | LeaveMessage | Message;
|
|
25
|
+
export type FromServerMessage = PeerMessage | ErrorMessage | Message;
|
|
26
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,2BAA2B,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,yBAAyB,EAAE,eAAe,EAAE,CAAA;CAC7C,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,uBAAuB,EAAE,eAAe,CAAA;IACxC,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAGD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAA;AACpE,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo-network-websocket",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "isomorphic node/browser Websocket network adapter for Automerge Repo",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@automerge/automerge": "^2.1.0-alpha.10"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"test": "mocha --no-warnings --experimental-specifier-resolution=node --exit"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@automerge/automerge-repo": "^1.0.0-alpha.
|
|
20
|
+
"@automerge/automerge-repo": "^1.0.0-alpha.3",
|
|
21
21
|
"cbor-x": "^1.3.0",
|
|
22
22
|
"eventemitter3": "^4.0.7",
|
|
23
23
|
"isomorphic-ws": "^5.0.0",
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "0ed108273084319aeea64ceccb49c3d58709f107"
|
|
38
38
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ChannelId,
|
|
3
|
-
InboundMessagePayload,
|
|
4
|
-
NetworkAdapter,
|
|
5
|
-
PeerId,
|
|
6
|
-
} from "@automerge/automerge-repo"
|
|
1
|
+
import { NetworkAdapter, PeerId } from "@automerge/automerge-repo"
|
|
7
2
|
import * as CBOR from "cbor-x"
|
|
8
3
|
import WebSocket from "isomorphic-ws"
|
|
9
4
|
|
|
10
5
|
import debug from "debug"
|
|
11
|
-
|
|
12
|
-
import {
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
FromClientMessage,
|
|
9
|
+
FromServerMessage,
|
|
10
|
+
JoinMessage,
|
|
11
|
+
} from "./messages.js"
|
|
12
|
+
import { ProtocolV1 } from "./protocolVersion.js"
|
|
13
|
+
import { isValidMessage } from "@automerge/automerge-repo/dist/network/messages.js"
|
|
14
|
+
|
|
13
15
|
const log = debug("WebsocketClient")
|
|
14
16
|
|
|
15
17
|
abstract class WebSocketNetworkAdapter extends NetworkAdapter {
|
|
@@ -17,9 +19,10 @@ abstract class WebSocketNetworkAdapter extends NetworkAdapter {
|
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
20
|
-
// Type trickery required for platform independence,
|
|
22
|
+
// Type trickery required for platform independence,
|
|
21
23
|
// see https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window
|
|
22
24
|
timerId?: ReturnType<typeof setTimeout>
|
|
25
|
+
|
|
23
26
|
url: string
|
|
24
27
|
|
|
25
28
|
constructor(url: string) {
|
|
@@ -62,9 +65,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
62
65
|
throw new Error("WTF, get a socket")
|
|
63
66
|
}
|
|
64
67
|
if (this.socket.readyState === WebSocket.OPEN) {
|
|
65
|
-
this.
|
|
66
|
-
CBOR.encode(joinMessage(this.peerId))
|
|
67
|
-
)
|
|
68
|
+
this.send(joinMessage(this.peerId!))
|
|
68
69
|
} else {
|
|
69
70
|
this.socket.addEventListener(
|
|
70
71
|
"open",
|
|
@@ -72,9 +73,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
72
73
|
if (!this.socket) {
|
|
73
74
|
throw new Error("WTF, get a socket")
|
|
74
75
|
}
|
|
75
|
-
this.
|
|
76
|
-
CBOR.encode(joinMessage(this.peerId))
|
|
77
|
-
)
|
|
76
|
+
this.send(joinMessage(this.peerId!))
|
|
78
77
|
},
|
|
79
78
|
{ once: true }
|
|
80
79
|
)
|
|
@@ -85,43 +84,31 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
85
84
|
if (!this.socket) {
|
|
86
85
|
throw new Error("WTF, get a socket")
|
|
87
86
|
}
|
|
88
|
-
this.
|
|
87
|
+
this.send({ type: "leave", senderId: this.peerId! })
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
channelId: ChannelId,
|
|
94
|
-
message: Uint8Array,
|
|
95
|
-
broadcast: boolean
|
|
96
|
-
) {
|
|
97
|
-
if (message.byteLength === 0) {
|
|
90
|
+
send(message: FromClientMessage) {
|
|
91
|
+
if ("data" in message && message.data.byteLength === 0) {
|
|
98
92
|
throw new Error("tried to send a zero-length message")
|
|
99
93
|
}
|
|
94
|
+
|
|
100
95
|
if (!this.peerId) {
|
|
101
96
|
throw new Error("Why don't we have a PeerID?")
|
|
102
97
|
}
|
|
103
98
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
targetId,
|
|
107
|
-
channelId,
|
|
108
|
-
type: "sync",
|
|
109
|
-
message,
|
|
110
|
-
broadcast,
|
|
99
|
+
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
100
|
+
throw new Error("Websocket Socket not ready!")
|
|
111
101
|
}
|
|
112
102
|
|
|
113
|
-
const encoded = CBOR.encode(
|
|
114
|
-
|
|
103
|
+
const encoded = CBOR.encode(message)
|
|
115
104
|
// This incantation deals with websocket sending the whole
|
|
116
105
|
// underlying buffer even if we just have a uint8array view on it
|
|
117
106
|
const arrayBuf = encoded.buffer.slice(
|
|
118
107
|
encoded.byteOffset,
|
|
119
108
|
encoded.byteOffset + encoded.byteLength
|
|
120
109
|
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
this.socket.send(arrayBuf)
|
|
110
|
+
|
|
111
|
+
this.socket?.send(arrayBuf)
|
|
125
112
|
}
|
|
126
113
|
|
|
127
114
|
announceConnection(peerId: PeerId) {
|
|
@@ -135,16 +122,9 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
135
122
|
}
|
|
136
123
|
|
|
137
124
|
receiveMessage(message: Uint8Array) {
|
|
138
|
-
const decoded:
|
|
125
|
+
const decoded: FromServerMessage = CBOR.decode(new Uint8Array(message))
|
|
139
126
|
|
|
140
|
-
const {
|
|
141
|
-
type,
|
|
142
|
-
senderId,
|
|
143
|
-
targetId,
|
|
144
|
-
channelId,
|
|
145
|
-
message: messageData,
|
|
146
|
-
broadcast,
|
|
147
|
-
} = decoded
|
|
127
|
+
const { type, senderId } = decoded
|
|
148
128
|
|
|
149
129
|
const socket = this.socket
|
|
150
130
|
if (!socket) {
|
|
@@ -157,24 +137,22 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
157
137
|
|
|
158
138
|
switch (type) {
|
|
159
139
|
case "peer":
|
|
160
|
-
log(`peer: ${senderId}
|
|
140
|
+
log(`peer: ${senderId}`)
|
|
161
141
|
this.announceConnection(senderId)
|
|
162
142
|
break
|
|
163
143
|
case "error":
|
|
164
|
-
log(`error: ${decoded.
|
|
144
|
+
log(`error: ${decoded.message}`)
|
|
145
|
+
break
|
|
165
146
|
default:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
message: new Uint8Array(messageData),
|
|
171
|
-
broadcast,
|
|
172
|
-
})
|
|
147
|
+
if (!isValidMessage(decoded)) {
|
|
148
|
+
throw new Error("Invalid message received")
|
|
149
|
+
}
|
|
150
|
+
this.emit("message", decoded)
|
|
173
151
|
}
|
|
174
152
|
}
|
|
175
153
|
}
|
|
176
154
|
|
|
177
|
-
function joinMessage(senderId
|
|
155
|
+
function joinMessage(senderId: PeerId): JoinMessage {
|
|
178
156
|
return {
|
|
179
157
|
type: "join",
|
|
180
158
|
senderId,
|
|
@@ -4,14 +4,13 @@ import { WebSocket, type WebSocketServer } from "isomorphic-ws"
|
|
|
4
4
|
import debug from "debug"
|
|
5
5
|
const log = debug("WebsocketServer")
|
|
6
6
|
|
|
7
|
+
import { ProtocolV1, ProtocolVersion } from "./protocolVersion.js"
|
|
7
8
|
import {
|
|
8
|
-
ChannelId,
|
|
9
|
-
InboundMessagePayload,
|
|
10
9
|
NetworkAdapter,
|
|
11
|
-
|
|
10
|
+
type NetworkAdapterMessage,
|
|
11
|
+
type PeerId,
|
|
12
12
|
} from "@automerge/automerge-repo"
|
|
13
|
-
import {
|
|
14
|
-
import { InboundWebSocketMessage } from "./message.js"
|
|
13
|
+
import { FromClientMessage, FromServerMessage } from "./messages.js"
|
|
15
14
|
|
|
16
15
|
export class NodeWSServerAdapter extends NetworkAdapter {
|
|
17
16
|
server: WebSocketServer
|
|
@@ -49,34 +48,21 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
49
48
|
// throw new Error("The server doesn't join channels.")
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
channelId: ChannelId,
|
|
55
|
-
message: Uint8Array,
|
|
56
|
-
broadcast: boolean
|
|
57
|
-
) {
|
|
58
|
-
if (message.byteLength === 0) {
|
|
51
|
+
send(message: FromServerMessage) {
|
|
52
|
+
if ("data" in message && message.data.byteLength === 0) {
|
|
59
53
|
throw new Error("tried to send a zero-length message")
|
|
60
54
|
}
|
|
61
55
|
const senderId = this.peerId
|
|
62
56
|
if (!senderId) {
|
|
63
57
|
throw new Error("No peerId set for the websocket server network adapter.")
|
|
64
58
|
}
|
|
65
|
-
if (this.sockets[targetId] === undefined) {
|
|
66
|
-
log(`Tried to send message to disconnected peer: ${targetId}`)
|
|
67
|
-
return
|
|
68
|
-
}
|
|
69
59
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
channelId,
|
|
74
|
-
type: "sync",
|
|
75
|
-
message,
|
|
76
|
-
broadcast,
|
|
60
|
+
if (this.sockets[message.targetId] === undefined) {
|
|
61
|
+
log(`Tried to send message to disconnected peer: ${message.targetId}`)
|
|
62
|
+
return
|
|
77
63
|
}
|
|
78
|
-
const encoded = CBOR.encode(decoded)
|
|
79
64
|
|
|
65
|
+
const encoded = CBOR.encode(message)
|
|
80
66
|
// This incantation deals with websocket sending the whole
|
|
81
67
|
// underlying buffer even if we just have a uint8array view on it
|
|
82
68
|
const arrayBuf = encoded.buffer.slice(
|
|
@@ -84,32 +70,22 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
84
70
|
encoded.byteOffset + encoded.byteLength
|
|
85
71
|
)
|
|
86
72
|
|
|
87
|
-
|
|
88
|
-
`[${senderId}->${targetId}@${channelId}] "sync" | ${arrayBuf.byteLength} bytes`
|
|
89
|
-
)
|
|
90
|
-
|
|
91
|
-
this.sockets[targetId].send(arrayBuf)
|
|
73
|
+
this.sockets[message.targetId]?.send(arrayBuf)
|
|
92
74
|
}
|
|
93
75
|
|
|
94
76
|
receiveMessage(message: Uint8Array, socket: WebSocket) {
|
|
95
|
-
const cbor:
|
|
96
|
-
|
|
97
|
-
const {
|
|
98
|
-
type,
|
|
99
|
-
channelId,
|
|
100
|
-
senderId,
|
|
101
|
-
targetId,
|
|
102
|
-
message: data,
|
|
103
|
-
broadcast,
|
|
104
|
-
supportedProtocolVersions,
|
|
105
|
-
} = cbor
|
|
77
|
+
const cbor: FromClientMessage = CBOR.decode(message)
|
|
78
|
+
|
|
79
|
+
const { type, senderId } = cbor
|
|
106
80
|
|
|
107
81
|
const myPeerId = this.peerId
|
|
108
82
|
if (!myPeerId) {
|
|
109
83
|
throw new Error("Missing my peer ID.")
|
|
110
84
|
}
|
|
111
85
|
log(
|
|
112
|
-
`[${senderId}->${myPeerId}
|
|
86
|
+
`[${senderId}->${myPeerId}${
|
|
87
|
+
"documentId" in cbor ? "@" + cbor.documentId : ""
|
|
88
|
+
}] ${type} | ${message.byteLength} bytes`
|
|
113
89
|
)
|
|
114
90
|
switch (type) {
|
|
115
91
|
case "join":
|
|
@@ -120,25 +96,24 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
120
96
|
// In this client-server connection, there's only ever one peer: us!
|
|
121
97
|
// (and we pretend to be joined to every channel)
|
|
122
98
|
const selectedProtocolVersion = selectProtocol(
|
|
123
|
-
supportedProtocolVersions
|
|
99
|
+
cbor.supportedProtocolVersions
|
|
124
100
|
)
|
|
125
101
|
if (selectedProtocolVersion === null) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
)
|
|
102
|
+
this.send({
|
|
103
|
+
type: "error",
|
|
104
|
+
senderId: this.peerId!,
|
|
105
|
+
message: "unsupported protocol version",
|
|
106
|
+
targetId: senderId,
|
|
107
|
+
})
|
|
132
108
|
this.sockets[senderId].close()
|
|
133
109
|
delete this.sockets[senderId]
|
|
134
110
|
} else {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
)
|
|
111
|
+
this.send({
|
|
112
|
+
type: "peer",
|
|
113
|
+
senderId: this.peerId!,
|
|
114
|
+
selectedProtocolVersion: ProtocolV1,
|
|
115
|
+
targetId: senderId,
|
|
116
|
+
})
|
|
142
117
|
}
|
|
143
118
|
break
|
|
144
119
|
case "leave":
|
|
@@ -148,21 +123,8 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
148
123
|
// ?
|
|
149
124
|
break
|
|
150
125
|
|
|
151
|
-
// We accept both "message" and "sync" because a previous version of this
|
|
152
|
-
// codebase sent sync messages in the BrowserWebSocketClientAdapter as
|
|
153
|
-
// type "message" and we want to stay backwards compatible
|
|
154
|
-
case "message":
|
|
155
|
-
case "sync":
|
|
156
|
-
this.emit("message", {
|
|
157
|
-
senderId,
|
|
158
|
-
targetId,
|
|
159
|
-
channelId,
|
|
160
|
-
message: new Uint8Array(data),
|
|
161
|
-
broadcast,
|
|
162
|
-
})
|
|
163
|
-
break
|
|
164
126
|
default:
|
|
165
|
-
|
|
127
|
+
this.emit("message", cbor)
|
|
166
128
|
break
|
|
167
129
|
}
|
|
168
130
|
}
|
package/src/messages.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type Message, type PeerId } from "@automerge/automerge-repo"
|
|
2
|
+
import { ProtocolVersion } from "./protocolVersion.js"
|
|
3
|
+
|
|
4
|
+
export type LeaveMessage = {
|
|
5
|
+
type: "leave"
|
|
6
|
+
senderId: PeerId
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type JoinMessage = {
|
|
10
|
+
type: "join"
|
|
11
|
+
senderId: PeerId
|
|
12
|
+
supportedProtocolVersions: ProtocolVersion[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type PeerMessage = {
|
|
16
|
+
type: "peer"
|
|
17
|
+
senderId: PeerId
|
|
18
|
+
selectedProtocolVersion: ProtocolVersion
|
|
19
|
+
targetId: PeerId
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type ErrorMessage = {
|
|
23
|
+
type: "error"
|
|
24
|
+
senderId: PeerId
|
|
25
|
+
message: string
|
|
26
|
+
targetId: PeerId
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// This adapter doesn't use NetworkAdapterMessage, it has its own idea of how to handle join/leave
|
|
30
|
+
export type FromClientMessage = JoinMessage | LeaveMessage | Message
|
|
31
|
+
export type FromServerMessage = PeerMessage | ErrorMessage | Message
|
package/test/Websocket.test.ts
CHANGED
|
@@ -3,17 +3,30 @@ import { BrowserWebSocketClientAdapter } from "../src/BrowserWebSocketClientAdap
|
|
|
3
3
|
import { NodeWSServerAdapter } from "../src/NodeWSServerAdapter"
|
|
4
4
|
import { startServer } from "./utilities/WebSockets"
|
|
5
5
|
import * as CBOR from "cbor-x"
|
|
6
|
-
import WebSocket, {AddressInfo}
|
|
6
|
+
import WebSocket, { AddressInfo } from "ws"
|
|
7
7
|
import { assert } from "chai"
|
|
8
|
-
import {
|
|
8
|
+
import { PeerId, Repo } from "@automerge/automerge-repo"
|
|
9
9
|
import { once } from "events"
|
|
10
10
|
|
|
11
11
|
describe("Websocket adapters", async () => {
|
|
12
12
|
let port = 8080
|
|
13
13
|
|
|
14
14
|
runAdapterTests(async () => {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
let socket: WebSocket.Server | undefined = undefined
|
|
16
|
+
let server: any
|
|
17
|
+
|
|
18
|
+
while (socket === undefined) {
|
|
19
|
+
try {
|
|
20
|
+
; ({ socket, server } = await startServer(port))
|
|
21
|
+
} catch (e: any) {
|
|
22
|
+
if (e.code === "EADDRINUSE") {
|
|
23
|
+
port++
|
|
24
|
+
} else {
|
|
25
|
+
throw e
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
17
30
|
const serverAdapter = new NodeWSServerAdapter(socket)
|
|
18
31
|
|
|
19
32
|
const serverUrl = `ws://localhost:${port}`
|
|
@@ -25,19 +38,19 @@ describe("Websocket adapters", async () => {
|
|
|
25
38
|
server.close()
|
|
26
39
|
}
|
|
27
40
|
|
|
28
|
-
return { adapters: [
|
|
41
|
+
return { adapters: [aliceAdapter, serverAdapter, bobAdapter], teardown }
|
|
29
42
|
})
|
|
30
43
|
})
|
|
31
44
|
|
|
32
45
|
describe("The BrowserWebSocketClientAdapter", () => {
|
|
33
46
|
it("should advertise the protocol versions it supports in its join message", async () => {
|
|
34
|
-
const
|
|
47
|
+
const { socket, server } = await startServer(0)
|
|
35
48
|
let port = (server.address()!! as AddressInfo).port
|
|
36
49
|
const serverUrl = `ws://localhost:${port}`
|
|
37
50
|
const helloPromise = firstMessage(socket)
|
|
38
51
|
|
|
39
52
|
const client = new BrowserWebSocketClientAdapter(serverUrl)
|
|
40
|
-
const repo = new Repo({network: [client], peerId: "browser" as PeerId})
|
|
53
|
+
const repo = new Repo({ network: [client], peerId: "browser" as PeerId })
|
|
41
54
|
|
|
42
55
|
const hello = await helloPromise
|
|
43
56
|
|
|
@@ -45,8 +58,8 @@ describe("The BrowserWebSocketClientAdapter", () => {
|
|
|
45
58
|
assert.deepEqual(message, {
|
|
46
59
|
type: "join",
|
|
47
60
|
senderId: "browser",
|
|
48
|
-
supportedProtocolVersions: ["1"]
|
|
49
|
-
})
|
|
61
|
+
supportedProtocolVersions: ["1"],
|
|
62
|
+
})
|
|
50
63
|
})
|
|
51
64
|
})
|
|
52
65
|
|
|
@@ -55,12 +68,13 @@ describe("The NodeWSServerAdapter", () => {
|
|
|
55
68
|
const response = await serverHelloGivenClientHello({
|
|
56
69
|
type: "join",
|
|
57
70
|
senderId: "browser",
|
|
58
|
-
supportedProtocolVersions: ["1"]
|
|
71
|
+
supportedProtocolVersions: ["1"],
|
|
59
72
|
})
|
|
60
73
|
assert.deepEqual<any>(response, {
|
|
61
74
|
type: "peer",
|
|
62
75
|
senderId: "server",
|
|
63
|
-
|
|
76
|
+
targetId: "browser",
|
|
77
|
+
selectedProtocolVersion: "1",
|
|
64
78
|
})
|
|
65
79
|
})
|
|
66
80
|
|
|
@@ -68,11 +82,13 @@ describe("The NodeWSServerAdapter", () => {
|
|
|
68
82
|
const response = await serverHelloGivenClientHello({
|
|
69
83
|
type: "join",
|
|
70
84
|
senderId: "browser",
|
|
71
|
-
supportedProtocolVersions: ["fake"]
|
|
85
|
+
supportedProtocolVersions: ["fake"],
|
|
72
86
|
})
|
|
73
87
|
assert.deepEqual<any>(response, {
|
|
74
88
|
type: "error",
|
|
75
|
-
|
|
89
|
+
senderId: "server",
|
|
90
|
+
targetId: "browser",
|
|
91
|
+
message: "unsupported protocol version",
|
|
76
92
|
})
|
|
77
93
|
})
|
|
78
94
|
|
|
@@ -84,17 +100,20 @@ describe("The NodeWSServerAdapter", () => {
|
|
|
84
100
|
assert.deepEqual<any>(response, {
|
|
85
101
|
type: "peer",
|
|
86
102
|
senderId: "server",
|
|
87
|
-
|
|
103
|
+
targetId: "browser",
|
|
104
|
+
selectedProtocolVersion: "1",
|
|
88
105
|
})
|
|
89
106
|
})
|
|
90
107
|
})
|
|
91
108
|
|
|
92
|
-
async function serverHelloGivenClientHello(
|
|
93
|
-
|
|
109
|
+
async function serverHelloGivenClientHello(
|
|
110
|
+
clientHello: Object
|
|
111
|
+
): Promise<Object | null> {
|
|
112
|
+
const { socket, server } = await startServer(0)
|
|
94
113
|
let port = (server.address()!! as AddressInfo).port
|
|
95
114
|
const serverUrl = `ws://localhost:${port}`
|
|
96
115
|
const adapter = new NodeWSServerAdapter(socket)
|
|
97
|
-
const repo = new Repo({network: [adapter], peerId: "server" as PeerId})
|
|
116
|
+
const repo = new Repo({ network: [adapter], peerId: "server" as PeerId })
|
|
98
117
|
|
|
99
118
|
const clientSocket = new WebSocket(serverUrl)
|
|
100
119
|
await once(clientSocket, "open")
|
|
@@ -107,9 +126,11 @@ async function serverHelloGivenClientHello(clientHello: Object): Promise<Object
|
|
|
107
126
|
return message
|
|
108
127
|
}
|
|
109
128
|
|
|
110
|
-
async function firstMessage(
|
|
129
|
+
async function firstMessage(
|
|
130
|
+
socket: WebSocket.Server<any>
|
|
131
|
+
): Promise<Object | null> {
|
|
111
132
|
return new Promise((resolve, reject) => {
|
|
112
|
-
socket.once("connection",
|
|
133
|
+
socket.once("connection", ws => {
|
|
113
134
|
ws.once("message", (message: any) => {
|
|
114
135
|
resolve(message)
|
|
115
136
|
})
|
|
@@ -117,7 +138,7 @@ async function firstMessage(socket: WebSocket.Server<any>): Promise<Object | nul
|
|
|
117
138
|
reject(error)
|
|
118
139
|
})
|
|
119
140
|
})
|
|
120
|
-
socket.once("error",
|
|
141
|
+
socket.once("error", error => {
|
|
121
142
|
reject(error)
|
|
122
143
|
})
|
|
123
144
|
})
|
package/dist/message.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type InboundMessagePayload } from "@automerge/automerge-repo";
|
|
2
|
-
import { ProtocolVersion } from "./protocolVersion.js";
|
|
3
|
-
export interface InboundWebSocketMessage extends InboundMessagePayload {
|
|
4
|
-
supportedProtocolVersions?: ProtocolVersion[];
|
|
5
|
-
}
|
|
6
|
-
export interface OutboundWebSocketMessage extends InboundMessagePayload {
|
|
7
|
-
errorMessage?: string;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=message.d.ts.map
|
package/dist/message.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,yBAAyB,CAAC,EAAE,eAAe,EAAE,CAAA;CAC9C;AAED,MAAM,WAAW,wBAAyB,SAAQ,qBAAqB;IACrE,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB"}
|
package/src/message.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type InboundMessagePayload } from "@automerge/automerge-repo"
|
|
2
|
-
import { ProtocolVersion } from "./protocolVersion.js"
|
|
3
|
-
|
|
4
|
-
export interface InboundWebSocketMessage extends InboundMessagePayload {
|
|
5
|
-
supportedProtocolVersions?: ProtocolVersion[]
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface OutboundWebSocketMessage extends InboundMessagePayload {
|
|
9
|
-
errorMessage?: string
|
|
10
|
-
}
|
|
File without changes
|