@automerge/automerge-repo-network-messagechannel 1.2.1 → 2.0.0-alpha.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.
@@ -5,6 +5,7 @@ export interface PortRefEvents {
5
5
  }
6
6
  export interface MessagePortRef extends EventEmitter<PortRefEvents> {
7
7
  start(): void;
8
+ stop(): void;
8
9
  postMessage(message: any, transferable?: Transferable[]): void;
9
10
  isAlive(): boolean;
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MessagePortRef.d.ts","sourceRoot":"","sources":["../src/MessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY,CAAC,aAAa,CAAC;IACjE,KAAK,IAAI,IAAI,CAAA;IACb,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAA;IAC9D,OAAO,IAAI,OAAO,CAAA;CACnB"}
1
+ {"version":3,"file":"MessagePortRef.d.ts","sourceRoot":"","sources":["../src/MessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY,CAAC,aAAa,CAAC;IACjE,KAAK,IAAI,IAAI,CAAA;IACb,IAAI,IAAI,IAAI,CAAA;IACZ,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAA;IAC9D,OAAO,IAAI,OAAO,CAAA;CACnB"}
@@ -2,9 +2,11 @@ import { EventEmitter } from "eventemitter3";
2
2
  import { PortRefEvents, MessagePortRef } from "./MessagePortRef.js";
3
3
  export declare class StrongMessagePortRef extends EventEmitter<PortRefEvents> implements MessagePortRef {
4
4
  private port;
5
+ isDisconnected: boolean;
5
6
  constructor(port: MessagePort);
6
7
  postMessage(message: any, transfer: Transferable[]): void;
7
8
  start(): void;
9
+ stop(): void;
8
10
  isAlive(): boolean;
9
11
  }
10
12
  //# sourceMappingURL=StrongMessagePortRef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StrongMessagePortRef.d.ts","sourceRoot":"","sources":["../src/StrongMessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEnE,qBAAa,oBACX,SAAQ,YAAY,CAAC,aAAa,CAClC,YAAW,cAAc;IAEb,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,WAAW;IAQrC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIzD,KAAK,IAAI,IAAI;IAIb,OAAO,IAAI,OAAO;CAInB"}
1
+ {"version":3,"file":"StrongMessagePortRef.d.ts","sourceRoot":"","sources":["../src/StrongMessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEnE,qBAAa,oBACX,SAAQ,YAAY,CAAC,aAAa,CAClC,YAAW,cAAc;IAIb,OAAO,CAAC,IAAI;IAFxB,cAAc,EAAE,OAAO,CAAQ;gBAEX,IAAI,EAAE,WAAW;IAUrC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAMzD,KAAK,IAAI,IAAI;IAKb,IAAI;IAIJ,OAAO,IAAI,OAAO;CAInB"}
@@ -1,19 +1,28 @@
1
1
  import { EventEmitter } from "eventemitter3";
2
2
  export class StrongMessagePortRef extends EventEmitter {
3
3
  port;
4
+ isDisconnected = false;
4
5
  constructor(port) {
5
6
  port.addEventListener("message", event => {
6
- this.emit("message", event);
7
+ if (!this.isDisconnected) {
8
+ this.emit("message", event);
9
+ }
7
10
  });
8
11
  super();
9
12
  this.port = port;
10
13
  }
11
14
  postMessage(message, transfer) {
12
- this.port.postMessage(message, transfer);
15
+ if (!this.isDisconnected) {
16
+ this.port.postMessage(message, transfer);
17
+ }
13
18
  }
14
19
  start() {
20
+ this.isDisconnected = false;
15
21
  this.port.start();
16
22
  }
23
+ stop() {
24
+ this.isDisconnected = true;
25
+ }
17
26
  isAlive() {
18
27
  /* c8 ignore next */
19
28
  return true;
@@ -6,6 +6,7 @@ export declare class WeakMessagePortRef extends EventEmitter<PortRefEvents> impl
6
6
  constructor(port: MessagePort);
7
7
  postMessage(message: any, transfer: Transferable[]): void;
8
8
  start(): void;
9
+ stop(): void;
9
10
  private disconnnect;
10
11
  isAlive(): boolean;
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WeakMessagePortRef.d.ts","sourceRoot":"","sources":["../src/WeakMessagePortRef.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEnE,qBAAa,kBACX,SAAQ,YAAY,CAAC,aAAa,CAClC,YAAW,cAAc;IAEzB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,cAAc,CAAQ;gBAElB,IAAI,EAAE,WAAW;IAU7B,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAezD,KAAK,IAAI,IAAI;IAeb,OAAO,CAAC,WAAW;IAOnB,OAAO,IAAI,OAAO;CAYnB"}
1
+ {"version":3,"file":"WeakMessagePortRef.d.ts","sourceRoot":"","sources":["../src/WeakMessagePortRef.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEnE,qBAAa,kBACX,SAAQ,YAAY,CAAC,aAAa,CAClC,YAAW,cAAc;IAEzB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,cAAc,CAAQ;gBAElB,IAAI,EAAE,WAAW;IAY7B,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAmBzD,KAAK,IAAI,IAAI;IAiBb,IAAI;IAIJ,OAAO,CAAC,WAAW;IAOnB,OAAO,IAAI,OAAO;CAYnB"}
@@ -7,7 +7,9 @@ export class WeakMessagePortRef extends EventEmitter {
7
7
  super();
8
8
  this.weakRef = new WeakRef(port);
9
9
  port.addEventListener("message", event => {
10
- this.emit("message", event);
10
+ if (!this.isDisconnected) {
11
+ this.emit("message", event);
12
+ }
11
13
  });
12
14
  }
13
15
  postMessage(message, transfer) {
@@ -16,6 +18,9 @@ export class WeakMessagePortRef extends EventEmitter {
16
18
  this.disconnnect();
17
19
  return;
18
20
  }
21
+ if (this.isDisconnected) {
22
+ return;
23
+ }
19
24
  try {
20
25
  port.postMessage(message, transfer);
21
26
  }
@@ -29,6 +34,7 @@ export class WeakMessagePortRef extends EventEmitter {
29
34
  this.disconnnect();
30
35
  return;
31
36
  }
37
+ this.isDisconnected = false;
32
38
  try {
33
39
  port.start();
34
40
  }
@@ -36,6 +42,9 @@ export class WeakMessagePortRef extends EventEmitter {
36
42
  this.disconnnect();
37
43
  }
38
44
  }
45
+ stop() {
46
+ this.isDisconnected = true;
47
+ }
39
48
  disconnnect() {
40
49
  if (!this.isDisconnected) {
41
50
  this.emit("close");
package/dist/index.d.ts CHANGED
@@ -12,6 +12,8 @@ export declare class MessageChannelNetworkAdapter extends NetworkAdapter {
12
12
  channels: {};
13
13
  /** @hidden */
14
14
  messagePortRef: MessagePortRef;
15
+ isReady(): boolean;
16
+ whenReady(): Promise<void>;
15
17
  constructor(messagePort: MessagePort, config?: MessageChannelNetworkAdapterConfig);
16
18
  connect(peerId: PeerId, peerMetadata?: PeerMetadata): void;
17
19
  send(message: RepoMessage): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,MAAM,EAEX,YAAY,EACb,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOpD,qBAAa,4BAA6B,SAAQ,cAAc;;IAC9D,QAAQ,KAAK;IACb,cAAc;IACd,cAAc,EAAE,cAAc,CAAA;gBAI5B,WAAW,EAAE,WAAW,EACxB,MAAM,GAAE,kCAAuC;IAWjD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY;IAyEnD,IAAI,CAAC,OAAO,EAAE,WAAW;IAmBzB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY;IAQ7D,UAAU;CAIX;AAED,MAAM,WAAW,kCAAkC;IACjD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,KAAK,WAAW,EAChB,cAAc,EACd,KAAK,MAAM,EAEX,YAAY,EACb,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOpD,qBAAa,4BAA6B,SAAQ,cAAc;;IAC9D,QAAQ,KAAK;IACb,cAAc;IACd,cAAc,EAAE,cAAc,CAAA;IAS9B,OAAO;IAIP,SAAS;gBAYP,WAAW,EAAE,WAAW,EACxB,MAAM,GAAE,kCAAuC;IAWjD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY;IA4EnD,IAAI,CAAC,OAAO,EAAE,WAAW;IAmBzB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY;IAM7D,UAAU;CAUX;AAED,MAAM,WAAW,kCAAkC;IACjD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB"}
package/dist/index.js CHANGED
@@ -14,7 +14,24 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
14
14
  channels = {};
15
15
  /** @hidden */
16
16
  messagePortRef;
17
- #startupComplete = false;
17
+ #ready = false;
18
+ #readyResolver;
19
+ #readyPromise = new Promise(resolve => {
20
+ this.#readyResolver = resolve;
21
+ });
22
+ #remotePeerId;
23
+ isReady() {
24
+ return this.#ready;
25
+ }
26
+ whenReady() {
27
+ return this.#readyPromise;
28
+ }
29
+ #forceReady() {
30
+ if (!this.#ready) {
31
+ this.#ready = true;
32
+ this.#readyResolver?.();
33
+ }
34
+ }
18
35
  constructor(messagePort, config = {}) {
19
36
  super();
20
37
  const useWeakRef = config.useWeakRef ?? false;
@@ -53,6 +70,11 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
53
70
  this.announceConnection(senderId, peerMetadata);
54
71
  }
55
72
  break;
73
+ case "leave":
74
+ if (this.#remotePeerId === senderId) {
75
+ this.emit("peer-disconnected", { peerId: senderId });
76
+ }
77
+ break;
56
78
  default:
57
79
  if (!("data" in message)) {
58
80
  this.emit("message", message);
@@ -78,10 +100,7 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
78
100
  // must be something weird going on on the other end to cause us to receive
79
101
  // no response
80
102
  setTimeout(() => {
81
- if (!this.#startupComplete) {
82
- this.#startupComplete = true;
83
- this.emit("ready", { network: this });
84
- }
103
+ this.#forceReady();
85
104
  }, 100);
86
105
  }
87
106
  send(message) {
@@ -97,14 +116,18 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
97
116
  }
98
117
  }
99
118
  announceConnection(peerId, peerMetadata) {
100
- if (!this.#startupComplete) {
101
- this.#startupComplete = true;
102
- this.emit("ready", { network: this });
103
- }
119
+ this.#remotePeerId = peerId;
120
+ this.#forceReady();
104
121
  this.emit("peer-candidate", { peerId, peerMetadata });
105
122
  }
106
123
  disconnect() {
107
- // TODO
108
- throw new Error("Unimplemented: leave on MessagePortNetworkAdapter");
124
+ if (this.#remotePeerId && this.peerId) {
125
+ this.messagePortRef.postMessage({
126
+ type: "leave",
127
+ senderId: this.peerId,
128
+ });
129
+ this.emit("peer-disconnected", { peerId: this.#remotePeerId });
130
+ }
131
+ this.messagePortRef.stop();
109
132
  }
110
133
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo-network-messagechannel",
3
- "version": "1.2.1",
3
+ "version": "2.0.0-alpha.1",
4
4
  "description": "MessageChannel network adapter for Automerge Repo",
5
5
  "repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo-network-messagechannel",
6
6
  "author": "Peter van Hardenberg <pvh@pvh.ca>",
@@ -13,7 +13,7 @@
13
13
  "test": "vitest"
14
14
  },
15
15
  "dependencies": {
16
- "@automerge/automerge-repo": "1.2.1",
16
+ "@automerge/automerge-repo": "2.0.0-alpha.1",
17
17
  "debug": "^4.3.4",
18
18
  "eventemitter3": "^5.0.1"
19
19
  },
@@ -28,5 +28,5 @@
28
28
  "publishConfig": {
29
29
  "access": "public"
30
30
  },
31
- "gitHead": "2108823d685e855977defb75a938838a3734818b"
31
+ "gitHead": "86421aba21c8037b916ee93f962df1c121fef52b"
32
32
  }
@@ -7,6 +7,7 @@ export interface PortRefEvents {
7
7
 
8
8
  export interface MessagePortRef extends EventEmitter<PortRefEvents> {
9
9
  start(): void
10
+ stop(): void
10
11
  postMessage(message: any, transferable?: Transferable[]): void
11
12
  isAlive(): boolean
12
13
  }
@@ -5,22 +5,33 @@ export class StrongMessagePortRef
5
5
  extends EventEmitter<PortRefEvents>
6
6
  implements MessagePortRef
7
7
  {
8
+ isDisconnected: boolean = false
9
+
8
10
  constructor(private port: MessagePort) {
9
11
  port.addEventListener("message", event => {
10
- this.emit("message", event)
12
+ if (!this.isDisconnected) {
13
+ this.emit("message", event)
14
+ }
11
15
  })
12
16
 
13
17
  super()
14
18
  }
15
19
 
16
20
  postMessage(message: any, transfer: Transferable[]): void {
17
- this.port.postMessage(message, transfer)
21
+ if (!this.isDisconnected) {
22
+ this.port.postMessage(message, transfer)
23
+ }
18
24
  }
19
25
 
20
26
  start(): void {
27
+ this.isDisconnected = false
21
28
  this.port.start()
22
29
  }
23
30
 
31
+ stop() {
32
+ this.isDisconnected = true
33
+ }
34
+
24
35
  isAlive(): boolean {
25
36
  /* c8 ignore next */
26
37
  return true
@@ -15,7 +15,9 @@ export class WeakMessagePortRef
15
15
  this.weakRef = new WeakRef<MessagePort>(port)
16
16
 
17
17
  port.addEventListener("message", event => {
18
- this.emit("message", event)
18
+ if (!this.isDisconnected) {
19
+ this.emit("message", event)
20
+ }
19
21
  })
20
22
  }
21
23
 
@@ -27,6 +29,10 @@ export class WeakMessagePortRef
27
29
  return
28
30
  }
29
31
 
32
+ if (this.isDisconnected) {
33
+ return
34
+ }
35
+
30
36
  try {
31
37
  port.postMessage(message, transfer)
32
38
  } catch (err) {
@@ -42,6 +48,8 @@ export class WeakMessagePortRef
42
48
  return
43
49
  }
44
50
 
51
+ this.isDisconnected = false
52
+
45
53
  try {
46
54
  port.start()
47
55
  } catch (err) {
@@ -49,6 +57,10 @@ export class WeakMessagePortRef
49
57
  }
50
58
  }
51
59
 
60
+ stop() {
61
+ this.isDisconnected = true
62
+ }
63
+
52
64
  private disconnnect() {
53
65
  if (!this.isDisconnected) {
54
66
  this.emit("close")
package/src/index.ts CHANGED
@@ -23,7 +23,28 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
23
23
  channels = {}
24
24
  /** @hidden */
25
25
  messagePortRef: MessagePortRef
26
- #startupComplete = false
26
+
27
+ #ready = false
28
+ #readyResolver?: () => void
29
+ #readyPromise: Promise<void> = new Promise<void>(resolve => {
30
+ this.#readyResolver = resolve
31
+ })
32
+ #remotePeerId?: PeerId
33
+
34
+ isReady() {
35
+ return this.#ready
36
+ }
37
+
38
+ whenReady() {
39
+ return this.#readyPromise
40
+ }
41
+
42
+ #forceReady() {
43
+ if (!this.#ready) {
44
+ this.#ready = true
45
+ this.#readyResolver?.()
46
+ }
47
+ }
27
48
 
28
49
  constructor(
29
50
  messagePort: MessagePort,
@@ -42,6 +63,7 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
42
63
  log("messageport connecting")
43
64
  this.peerId = peerId
44
65
  this.peerMetadata = peerMetadata
66
+
45
67
  this.messagePortRef.start()
46
68
  this.messagePortRef.addListener(
47
69
  "message",
@@ -76,6 +98,11 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
76
98
  this.announceConnection(senderId, peerMetadata)
77
99
  }
78
100
  break
101
+ case "leave":
102
+ if (this.#remotePeerId === senderId) {
103
+ this.emit("peer-disconnected", { peerId: senderId })
104
+ }
105
+ break
79
106
  default:
80
107
  if (!("data" in message)) {
81
108
  this.emit("message", message)
@@ -104,10 +131,7 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
104
131
  // must be something weird going on on the other end to cause us to receive
105
132
  // no response
106
133
  setTimeout(() => {
107
- if (!this.#startupComplete) {
108
- this.#startupComplete = true
109
- this.emit("ready", { network: this })
110
- }
134
+ this.#forceReady()
111
135
  }, 100)
112
136
  }
113
137
 
@@ -131,16 +155,20 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
131
155
  }
132
156
 
133
157
  announceConnection(peerId: PeerId, peerMetadata: PeerMetadata) {
134
- if (!this.#startupComplete) {
135
- this.#startupComplete = true
136
- this.emit("ready", { network: this })
137
- }
158
+ this.#remotePeerId = peerId
159
+ this.#forceReady()
138
160
  this.emit("peer-candidate", { peerId, peerMetadata })
139
161
  }
140
162
 
141
163
  disconnect() {
142
- // TODO
143
- throw new Error("Unimplemented: leave on MessagePortNetworkAdapter")
164
+ if (this.#remotePeerId && this.peerId) {
165
+ this.messagePortRef.postMessage({
166
+ type: "leave",
167
+ senderId: this.peerId,
168
+ })
169
+ this.emit("peer-disconnected", { peerId: this.#remotePeerId })
170
+ }
171
+ this.messagePortRef.stop()
144
172
  }
145
173
  }
146
174