@automerge/automerge-repo-network-websocket 1.0.0-alpha.3 → 1.0.0-alpha.4
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 +1 -0
- package/dist/BrowserWebSocketClientAdapter.d.ts.map +1 -1
- package/dist/BrowserWebSocketClientAdapter.js +17 -4
- package/dist/NodeWSServerAdapter.d.ts.map +1 -1
- package/dist/NodeWSServerAdapter.js +5 -4
- package/package.json +4 -4
- package/src/BrowserWebSocketClientAdapter.ts +18 -5
- package/src/NodeWSServerAdapter.ts +6 -3
- package/test/Websocket.test.ts +4 -4
- package/test/utilities/WebSockets.ts +1 -1
- package/tsconfig.json +2 -2
|
@@ -6,6 +6,7 @@ declare abstract class WebSocketNetworkAdapter extends NetworkAdapter {
|
|
|
6
6
|
socket?: WebSocket;
|
|
7
7
|
}
|
|
8
8
|
export declare class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
9
|
+
#private;
|
|
9
10
|
timerId?: ReturnType<typeof setTimeout>;
|
|
10
11
|
url: string;
|
|
11
12
|
constructor(url: string);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserWebSocketClientAdapter.d.ts","sourceRoot":"","sources":["../src/BrowserWebSocketClientAdapter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"BrowserWebSocketClientAdapter.d.ts","sourceRoot":"","sources":["../src/BrowserWebSocketClientAdapter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAQ,MAAM,2BAA2B,CAAA;AACxE,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;IAGvC,GAAG,EAAE,MAAM,CAAA;gBAEC,GAAG,EAAE,MAAM;IAKvB,OAAO,CAAC,MAAM,EAAE,MAAM;IAwCtB,IAAI;IAoBJ,KAAK;IAOL,IAAI,CAAC,OAAO,EAAE,iBAAiB;IAwB/B,kBAAkB,CAAC,MAAM,EAAE,MAAM;IAajC,cAAc,CAAC,OAAO,EAAE,UAAU;CA6BnC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { NetworkAdapter } from "@automerge/automerge-repo";
|
|
2
|
-
import * as CBOR from "cbor-x";
|
|
1
|
+
import { NetworkAdapter, cbor } from "@automerge/automerge-repo";
|
|
3
2
|
import WebSocket from "isomorphic-ws";
|
|
4
3
|
import debug from "debug";
|
|
5
4
|
import { ProtocolV1 } from "./protocolVersion.js";
|
|
@@ -12,6 +11,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
12
11
|
// Type trickery required for platform independence,
|
|
13
12
|
// see https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window
|
|
14
13
|
timerId;
|
|
14
|
+
#startupComplete = false;
|
|
15
15
|
url;
|
|
16
16
|
constructor(url) {
|
|
17
17
|
super();
|
|
@@ -39,6 +39,15 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
39
39
|
// log("Disconnected from server")
|
|
40
40
|
});
|
|
41
41
|
this.socket.addEventListener("message", (event) => this.receiveMessage(event.data));
|
|
42
|
+
// mark this adapter as ready if we haven't received an ack in 1 second.
|
|
43
|
+
// We might hear back from the other end at some point but we shouldn't
|
|
44
|
+
// hold up marking things as unavailable for any longer
|
|
45
|
+
setTimeout(() => {
|
|
46
|
+
if (!this.#startupComplete) {
|
|
47
|
+
this.#startupComplete = true;
|
|
48
|
+
this.emit("ready", { network: this });
|
|
49
|
+
}
|
|
50
|
+
}, 1000);
|
|
42
51
|
}
|
|
43
52
|
join() {
|
|
44
53
|
if (!this.socket) {
|
|
@@ -72,7 +81,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
72
81
|
if (!this.socket || this.socket.readyState !== WebSocket.OPEN) {
|
|
73
82
|
throw new Error("Websocket Socket not ready!");
|
|
74
83
|
}
|
|
75
|
-
const encoded =
|
|
84
|
+
const encoded = cbor.encode(message);
|
|
76
85
|
// This incantation deals with websocket sending the whole
|
|
77
86
|
// underlying buffer even if we just have a uint8array view on it
|
|
78
87
|
const arrayBuf = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
|
|
@@ -84,10 +93,14 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
84
93
|
if (!myPeerId) {
|
|
85
94
|
throw new Error("we should have a peer ID by now");
|
|
86
95
|
}
|
|
96
|
+
if (!this.#startupComplete) {
|
|
97
|
+
this.#startupComplete = true;
|
|
98
|
+
this.emit("ready", { network: this });
|
|
99
|
+
}
|
|
87
100
|
this.emit("peer-candidate", { peerId });
|
|
88
101
|
}
|
|
89
102
|
receiveMessage(message) {
|
|
90
|
-
const decoded =
|
|
103
|
+
const decoded = cbor.decode(new Uint8Array(message));
|
|
91
104
|
const { type, senderId } = decoded;
|
|
92
105
|
const socket = this.socket;
|
|
93
106
|
if (!socket) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeWSServerAdapter.d.ts","sourceRoot":"","sources":["../src/NodeWSServerAdapter.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"NodeWSServerAdapter.d.ts","sourceRoot":"","sources":["../src/NodeWSServerAdapter.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAM/D,OAAO,EACL,cAAc,EAGd,KAAK,MAAM,EACZ,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAqB,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAIpE,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;IAoBtB,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
|
-
import * as CBOR from "cbor-x";
|
|
2
1
|
import debug from "debug";
|
|
3
2
|
const log = debug("WebsocketServer");
|
|
4
3
|
import { ProtocolV1 } from "./protocolVersion.js";
|
|
5
|
-
import { NetworkAdapter, } from "@automerge/automerge-repo";
|
|
4
|
+
import { NetworkAdapter, cbor as cborHelpers, } from "@automerge/automerge-repo";
|
|
5
|
+
const { encode, decode } = cborHelpers;
|
|
6
6
|
export class NodeWSServerAdapter extends NetworkAdapter {
|
|
7
7
|
server;
|
|
8
8
|
sockets = {};
|
|
@@ -23,6 +23,7 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
socket.on("message", message => this.receiveMessage(message, socket));
|
|
26
|
+
this.emit("ready", { network: this });
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
29
|
join() {
|
|
@@ -43,14 +44,14 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
43
44
|
log(`Tried to send message to disconnected peer: ${message.targetId}`);
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
|
-
const encoded =
|
|
47
|
+
const encoded = encode(message);
|
|
47
48
|
// This incantation deals with websocket sending the whole
|
|
48
49
|
// underlying buffer even if we just have a uint8array view on it
|
|
49
50
|
const arrayBuf = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
|
|
50
51
|
this.sockets[message.targetId]?.send(arrayBuf);
|
|
51
52
|
}
|
|
52
53
|
receiveMessage(message, socket) {
|
|
53
|
-
const cbor =
|
|
54
|
+
const cbor = decode(message);
|
|
54
55
|
const { type, senderId } = cbor;
|
|
55
56
|
const myPeerId = this.peerId;
|
|
56
57
|
if (!myPeerId) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automerge/automerge-repo-network-websocket",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.4",
|
|
4
4
|
"description": "isomorphic node/browser Websocket network adapter for Automerge Repo",
|
|
5
5
|
"peerDependencies": {
|
|
6
|
-
"@automerge/automerge": "^2.1.0-alpha.
|
|
6
|
+
"@automerge/automerge": "^2.1.0-alpha.12"
|
|
7
7
|
},
|
|
8
8
|
"repository": "https://github.com/automerge/automerge-repo",
|
|
9
9
|
"author": "Peter van Hardenberg <pvh@pvh.ca>",
|
|
@@ -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.4",
|
|
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": "fbf71f0c3aaa2786a4e279f336f01d665f53ce5b"
|
|
38
38
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { NetworkAdapter, PeerId } from "@automerge/automerge-repo"
|
|
2
|
-
import * as CBOR from "cbor-x"
|
|
1
|
+
import { NetworkAdapter, PeerId, cbor } from "@automerge/automerge-repo"
|
|
3
2
|
import WebSocket from "isomorphic-ws"
|
|
4
3
|
|
|
5
4
|
import debug from "debug"
|
|
@@ -22,6 +21,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
22
21
|
// Type trickery required for platform independence,
|
|
23
22
|
// see https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window
|
|
24
23
|
timerId?: ReturnType<typeof setTimeout>
|
|
24
|
+
#startupComplete: boolean = false
|
|
25
25
|
|
|
26
26
|
url: string
|
|
27
27
|
|
|
@@ -58,6 +58,16 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
58
58
|
this.socket.addEventListener("message", (event: WebSocket.MessageEvent) =>
|
|
59
59
|
this.receiveMessage(event.data as Uint8Array)
|
|
60
60
|
)
|
|
61
|
+
|
|
62
|
+
// mark this adapter as ready if we haven't received an ack in 1 second.
|
|
63
|
+
// We might hear back from the other end at some point but we shouldn't
|
|
64
|
+
// hold up marking things as unavailable for any longer
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
if (!this.#startupComplete) {
|
|
67
|
+
this.#startupComplete = true
|
|
68
|
+
this.emit("ready", { network: this })
|
|
69
|
+
}
|
|
70
|
+
}, 1000)
|
|
61
71
|
}
|
|
62
72
|
|
|
63
73
|
join() {
|
|
@@ -100,7 +110,7 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
100
110
|
throw new Error("Websocket Socket not ready!")
|
|
101
111
|
}
|
|
102
112
|
|
|
103
|
-
const encoded =
|
|
113
|
+
const encoded = cbor.encode(message)
|
|
104
114
|
// This incantation deals with websocket sending the whole
|
|
105
115
|
// underlying buffer even if we just have a uint8array view on it
|
|
106
116
|
const arrayBuf = encoded.buffer.slice(
|
|
@@ -117,12 +127,15 @@ export class BrowserWebSocketClientAdapter extends WebSocketNetworkAdapter {
|
|
|
117
127
|
if (!myPeerId) {
|
|
118
128
|
throw new Error("we should have a peer ID by now")
|
|
119
129
|
}
|
|
120
|
-
|
|
130
|
+
if (!this.#startupComplete) {
|
|
131
|
+
this.#startupComplete = true
|
|
132
|
+
this.emit("ready", { network: this })
|
|
133
|
+
}
|
|
121
134
|
this.emit("peer-candidate", { peerId })
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
receiveMessage(message: Uint8Array) {
|
|
125
|
-
const decoded: FromServerMessage =
|
|
138
|
+
const decoded: FromServerMessage = cbor.decode(new Uint8Array(message))
|
|
126
139
|
|
|
127
140
|
const { type, senderId } = decoded
|
|
128
141
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as CBOR from "cbor-x"
|
|
2
1
|
import { WebSocket, type WebSocketServer } from "isomorphic-ws"
|
|
3
2
|
|
|
4
3
|
import debug from "debug"
|
|
@@ -7,11 +6,14 @@ const log = debug("WebsocketServer")
|
|
|
7
6
|
import { ProtocolV1, ProtocolVersion } from "./protocolVersion.js"
|
|
8
7
|
import {
|
|
9
8
|
NetworkAdapter,
|
|
9
|
+
cbor as cborHelpers,
|
|
10
10
|
type NetworkAdapterMessage,
|
|
11
11
|
type PeerId,
|
|
12
12
|
} from "@automerge/automerge-repo"
|
|
13
13
|
import { FromClientMessage, FromServerMessage } from "./messages.js"
|
|
14
14
|
|
|
15
|
+
const { encode, decode } = cborHelpers
|
|
16
|
+
|
|
15
17
|
export class NodeWSServerAdapter extends NetworkAdapter {
|
|
16
18
|
server: WebSocketServer
|
|
17
19
|
sockets: { [peerId: PeerId]: WebSocket } = {}
|
|
@@ -37,6 +39,7 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
37
39
|
socket.on("message", message =>
|
|
38
40
|
this.receiveMessage(message as Uint8Array, socket)
|
|
39
41
|
)
|
|
42
|
+
this.emit("ready", {network: this})
|
|
40
43
|
})
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -62,7 +65,7 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
62
65
|
return
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
const encoded =
|
|
68
|
+
const encoded = encode(message)
|
|
66
69
|
// This incantation deals with websocket sending the whole
|
|
67
70
|
// underlying buffer even if we just have a uint8array view on it
|
|
68
71
|
const arrayBuf = encoded.buffer.slice(
|
|
@@ -74,7 +77,7 @@ export class NodeWSServerAdapter extends NetworkAdapter {
|
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
receiveMessage(message: Uint8Array, socket: WebSocket) {
|
|
77
|
-
const cbor: FromClientMessage =
|
|
80
|
+
const cbor: FromClientMessage = decode(message)
|
|
78
81
|
|
|
79
82
|
const { type, senderId } = cbor
|
|
80
83
|
|
package/test/Websocket.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { runAdapterTests } from "../../automerge-repo/src/helpers/tests/network-adapter-tests"
|
|
2
|
-
import { BrowserWebSocketClientAdapter } from "../src/BrowserWebSocketClientAdapter"
|
|
3
|
-
import { NodeWSServerAdapter } from "../src/NodeWSServerAdapter"
|
|
4
|
-
import { startServer } from "./utilities/WebSockets"
|
|
1
|
+
import { runAdapterTests } from "../../automerge-repo/src/helpers/tests/network-adapter-tests.js"
|
|
2
|
+
import { BrowserWebSocketClientAdapter } from "../src/BrowserWebSocketClientAdapter.js"
|
|
3
|
+
import { NodeWSServerAdapter } from "../src/NodeWSServerAdapter.js"
|
|
4
|
+
import { startServer } from "./utilities/WebSockets.js"
|
|
5
5
|
import * as CBOR from "cbor-x"
|
|
6
6
|
import WebSocket, { AddressInfo } from "ws"
|
|
7
7
|
import { assert } from "chai"
|
package/tsconfig.json
CHANGED