@automerge/automerge-repo-network-messagechannel 1.0.0-alpha.2 → 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/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- import { ChannelId, NetworkAdapter, PeerId } from "@automerge/automerge-repo";
1
+ import { type Message, NetworkAdapter, type PeerId } from "@automerge/automerge-repo";
2
2
  import { MessagePortRef } from "./MessagePortRef.js";
3
3
  export declare class MessageChannelNetworkAdapter extends NetworkAdapter {
4
+ #private;
4
5
  channels: {};
5
6
  messagePortRef: MessagePortRef;
6
7
  constructor(messagePort: MessagePort, config?: MessageChannelNetworkAdapterConfig);
7
8
  connect(peerId: PeerId): void;
8
- sendMessage(peerId: PeerId, channelId: ChannelId, uint8message: Uint8Array, broadcast: boolean): void;
9
+ send(message: Message): void;
9
10
  announceConnection(peerId: PeerId): void;
10
11
  join(): void;
11
12
  leave(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOpD,qBAAa,4BAA6B,SAAQ,cAAc;IAC9D,QAAQ,KAAK;IACb,cAAc,EAAE,cAAc,CAAA;gBAG5B,WAAW,EAAE,WAAW,EACxB,MAAM,GAAE,kCAAuC;IAWjD,OAAO,CAAC,MAAM,EAAE,MAAM;IA4CtB,WAAW,CACT,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,UAAU,EACxB,SAAS,EAAE,OAAO;IAmBpB,kBAAkB,CAAC,MAAM,EAAE,MAAM;IAIjC,IAAI;IAOJ,KAAK;CAIN;AAED,UAAU,kCAAkC;IAC1C;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,cAAc,EACd,KAAK,MAAM,EAEZ,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOpD,qBAAa,4BAA6B,SAAQ,cAAc;;IAC9D,QAAQ,KAAK;IACb,cAAc,EAAE,cAAc,CAAA;gBAI5B,WAAW,EAAE,WAAW,EACxB,MAAM,GAAE,kCAAuC;IAWjD,OAAO,CAAC,MAAM,EAAE,MAAM;IA4DtB,IAAI,CAAC,OAAO,EAAE,OAAO;IAmBrB,kBAAkB,CAAC,MAAM,EAAE,MAAM;IAQjC,IAAI;IAOJ,KAAK;CAIN;AAED,UAAU,kCAAkC;IAC1C;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { NetworkAdapter } from "@automerge/automerge-repo";
1
+ import { NetworkAdapter, } from "@automerge/automerge-repo";
2
2
  import { StrongMessagePortRef } from "./StrongMessagePortRef.js";
3
3
  import { WeakMessagePortRef } from "./WeakMessagePortRef.js";
4
4
  import debug from "debug";
@@ -6,6 +6,7 @@ const log = debug("automerge-repo:messagechannel");
6
6
  export class MessageChannelNetworkAdapter extends NetworkAdapter {
7
7
  channels = {};
8
8
  messagePortRef;
9
+ #startupComplete = false;
9
10
  constructor(messagePort, config = {}) {
10
11
  super();
11
12
  const useWeakRef = config.useWeakRef ?? false;
@@ -17,58 +18,74 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
17
18
  log("messageport connecting");
18
19
  this.peerId = peerId;
19
20
  this.messagePortRef.start();
20
- this.messagePortRef.addListener("message", e => {
21
+ this.messagePortRef.addListener("message", (e) => {
21
22
  log("message port received", e.data);
22
- const { origin, destination, type, channelId, message, broadcast } = e.data;
23
- if (destination && !(destination === this.peerId || broadcast)) {
23
+ const message = e.data;
24
+ if ("targetId" in message && message.targetId !== this.peerId) {
24
25
  throw new Error("MessagePortNetwork should never receive messages for a different peer.");
25
26
  }
27
+ const { senderId, type } = message;
26
28
  switch (type) {
27
29
  case "arrive":
28
30
  this.messagePortRef.postMessage({
29
- origin: this.peerId,
30
- destination: origin,
31
+ senderId: this.peerId,
32
+ targetId: senderId,
31
33
  type: "welcome",
32
34
  });
33
- this.announceConnection(origin);
35
+ this.announceConnection(senderId);
34
36
  break;
35
37
  case "welcome":
36
- this.announceConnection(origin);
37
- break;
38
- case "message":
39
- this.emit("message", {
40
- senderId: origin,
41
- targetId: destination,
42
- channelId,
43
- message: new Uint8Array(message),
44
- broadcast,
45
- });
38
+ this.announceConnection(senderId);
46
39
  break;
47
40
  default:
48
- throw new Error("unhandled message from network");
41
+ if (!("data" in message)) {
42
+ this.emit("message", message);
43
+ }
44
+ else {
45
+ this.emit("message", {
46
+ ...message,
47
+ data: new Uint8Array(message.data),
48
+ });
49
+ }
50
+ break;
49
51
  }
50
52
  });
51
53
  this.messagePortRef.addListener("close", () => {
52
54
  this.emit("close");
53
55
  });
56
+ this.join();
57
+ // Mark this messagechannel as ready after 50 ms, at this point there
58
+ // must be something weird going on on the other end to cause us to receive
59
+ // no response
60
+ setTimeout(() => {
61
+ if (!this.#startupComplete) {
62
+ this.#startupComplete = true;
63
+ this.emit("ready", { network: this });
64
+ }
65
+ }, 100);
54
66
  }
55
- sendMessage(peerId, channelId, uint8message, broadcast) {
56
- const message = uint8message.buffer.slice(uint8message.byteOffset, uint8message.byteOffset + uint8message.byteLength);
57
- this.messagePortRef.postMessage({
58
- origin: this.peerId,
59
- destination: peerId,
60
- channelId: channelId,
61
- type: "message",
62
- message,
63
- broadcast,
64
- }, [message]);
67
+ send(message) {
68
+ if ("data" in message) {
69
+ const data = message.data.buffer.slice(message.data.byteOffset, message.data.byteOffset + message.data.byteLength);
70
+ this.messagePortRef.postMessage({
71
+ ...message,
72
+ data,
73
+ }, [data]);
74
+ }
75
+ else {
76
+ this.messagePortRef.postMessage(message);
77
+ }
65
78
  }
66
79
  announceConnection(peerId) {
80
+ if (!this.#startupComplete) {
81
+ this.#startupComplete = true;
82
+ this.emit("ready", { network: this });
83
+ }
67
84
  this.emit("peer-candidate", { peerId });
68
85
  }
69
86
  join() {
70
87
  this.messagePortRef.postMessage({
71
- origin: this.peerId,
88
+ senderId: this.peerId,
72
89
  type: "arrive",
73
90
  });
74
91
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo-network-messagechannel",
3
- "version": "1.0.0-alpha.2",
3
+ "version": "1.0.0-alpha.4",
4
4
  "description": "MessageChannel network adapter for Automerge Repo",
5
5
  "repository": "https://github.com/automerge/automerge-repo",
6
6
  "author": "Peter van Hardenberg <pvh@pvh.ca>",
@@ -14,10 +14,10 @@
14
14
  "test": "mocha --no-warnings --experimental-specifier-resolution=node --exit"
15
15
  },
16
16
  "dependencies": {
17
- "@automerge/automerge-repo": "^1.0.0-alpha.2"
17
+ "@automerge/automerge-repo": "^1.0.0-alpha.4"
18
18
  },
19
19
  "peerDependencies": {
20
- "@automerge/automerge": "^2.1.0-alpha.10"
20
+ "@automerge/automerge": "^2.1.0-alpha.12"
21
21
  },
22
22
  "watch": {
23
23
  "build": {
@@ -30,5 +30,5 @@
30
30
  "publishConfig": {
31
31
  "access": "public"
32
32
  },
33
- "gitHead": "b5830dde8f135b694809698aaad2a9fdc79a9898"
33
+ "gitHead": "fbf71f0c3aaa2786a4e279f336f01d665f53ce5b"
34
34
  }
package/src/index.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { ChannelId, NetworkAdapter, PeerId } from "@automerge/automerge-repo"
1
+ import {
2
+ type Message,
3
+ NetworkAdapter,
4
+ type PeerId,
5
+ NetworkAdapterMessage,
6
+ } from "@automerge/automerge-repo"
2
7
  import { MessagePortRef } from "./MessagePortRef.js"
3
8
  import { StrongMessagePortRef } from "./StrongMessagePortRef.js"
4
9
  import { WeakMessagePortRef } from "./WeakMessagePortRef.js"
@@ -9,6 +14,7 @@ const log = debug("automerge-repo:messagechannel")
9
14
  export class MessageChannelNetworkAdapter extends NetworkAdapter {
10
15
  channels = {}
11
16
  messagePortRef: MessagePortRef
17
+ #startupComplete = false
12
18
 
13
19
  constructor(
14
20
  messagePort: MessagePort,
@@ -27,76 +33,92 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
27
33
  log("messageport connecting")
28
34
  this.peerId = peerId
29
35
  this.messagePortRef.start()
30
- this.messagePortRef.addListener("message", e => {
31
- log("message port received", e.data)
32
- const { origin, destination, type, channelId, message, broadcast } =
33
- e.data
34
- if (destination && !(destination === this.peerId || broadcast)) {
35
- throw new Error(
36
- "MessagePortNetwork should never receive messages for a different peer."
37
- )
38
- }
39
- switch (type) {
40
- case "arrive":
41
- this.messagePortRef.postMessage({
42
- origin: this.peerId,
43
- destination: origin,
44
- type: "welcome",
45
- })
46
- this.announceConnection(origin)
47
- break
48
- case "welcome":
49
- this.announceConnection(origin)
50
- break
51
- case "message":
52
- this.emit("message", {
53
- senderId: origin,
54
- targetId: destination,
55
- channelId,
56
- message: new Uint8Array(message),
57
- broadcast,
58
- })
59
- break
60
- default:
61
- throw new Error("unhandled message from network")
36
+ this.messagePortRef.addListener(
37
+ "message",
38
+ (e: { data: NetworkAdapterMessage }) => {
39
+ log("message port received", e.data)
40
+
41
+ const message = e.data
42
+ if ("targetId" in message && message.targetId !== this.peerId) {
43
+ throw new Error(
44
+ "MessagePortNetwork should never receive messages for a different peer."
45
+ )
46
+ }
47
+
48
+ const { senderId, type } = message
49
+
50
+ switch (type) {
51
+ case "arrive":
52
+ this.messagePortRef.postMessage({
53
+ senderId: this.peerId,
54
+ targetId: senderId,
55
+ type: "welcome",
56
+ })
57
+ this.announceConnection(senderId)
58
+ break
59
+ case "welcome":
60
+ this.announceConnection(senderId)
61
+ break
62
+ default:
63
+ if (!("data" in message)) {
64
+ this.emit("message", message)
65
+ } else {
66
+ this.emit("message", {
67
+ ...message,
68
+ data: new Uint8Array(message.data),
69
+ })
70
+ }
71
+ break
72
+ }
62
73
  }
63
- })
74
+ )
64
75
 
65
76
  this.messagePortRef.addListener("close", () => {
66
77
  this.emit("close")
67
78
  })
79
+ this.join()
80
+
81
+ // Mark this messagechannel as ready after 50 ms, at this point there
82
+ // must be something weird going on on the other end to cause us to receive
83
+ // no response
84
+ setTimeout(() => {
85
+ if (!this.#startupComplete) {
86
+ this.#startupComplete = true
87
+ this.emit("ready", { network: this })
88
+ }
89
+ }, 100)
68
90
  }
69
91
 
70
- sendMessage(
71
- peerId: PeerId,
72
- channelId: ChannelId,
73
- uint8message: Uint8Array,
74
- broadcast: boolean
75
- ) {
76
- const message = uint8message.buffer.slice(
77
- uint8message.byteOffset,
78
- uint8message.byteOffset + uint8message.byteLength
79
- )
80
- this.messagePortRef.postMessage(
81
- {
82
- origin: this.peerId,
83
- destination: peerId,
84
- channelId: channelId,
85
- type: "message",
86
- message,
87
- broadcast,
88
- },
89
- [message]
90
- )
92
+ send(message: Message) {
93
+ if ("data" in message) {
94
+ const data = message.data.buffer.slice(
95
+ message.data.byteOffset,
96
+ message.data.byteOffset + message.data.byteLength
97
+ )
98
+
99
+ this.messagePortRef.postMessage(
100
+ {
101
+ ...message,
102
+ data,
103
+ },
104
+ [data]
105
+ )
106
+ } else {
107
+ this.messagePortRef.postMessage(message)
108
+ }
91
109
  }
92
110
 
93
111
  announceConnection(peerId: PeerId) {
112
+ if (!this.#startupComplete) {
113
+ this.#startupComplete = true
114
+ this.emit("ready", { network: this })
115
+ }
94
116
  this.emit("peer-candidate", { peerId })
95
117
  }
96
118
 
97
119
  join() {
98
120
  this.messagePortRef.postMessage({
99
- origin: this.peerId,
121
+ senderId: this.peerId,
100
122
  type: "arrive",
101
123
  })
102
124
  }
@@ -1,5 +1,5 @@
1
- import { runAdapterTests } from "../../automerge-repo/src/helpers/tests/network-adapter-tests"
2
- import { MessageChannelNetworkAdapter as Adapter } from "../src"
1
+ import { runAdapterTests } from "../../automerge-repo/src/helpers/tests/network-adapter-tests.js"
2
+ import { MessageChannelNetworkAdapter as Adapter } from "../src/index.js"
3
3
 
4
4
  // bob is the hub, alice and charlie are spokes
5
5
  describe("MessageChannelNetworkAdapter", () => {
package/tsconfig.json CHANGED
@@ -2,8 +2,8 @@
2
2
  "compilerOptions": {
3
3
  "target": "ESNext",
4
4
  "jsx": "react",
5
- "module": "ESNext",
6
- "moduleResolution": "node",
5
+ "module": "NodeNext",
6
+ "moduleResolution": "Node16",
7
7
  "declaration": true,
8
8
  "declarationMap": true,
9
9
  "outDir": "./dist",