Skip to content

Commit 7d46c85

Browse files
Convert to using [NetworkAdapterInterface] (#4)
* rename * Update README.md * export t ypes * 0.0.12 * Update README.md * emit message events * implement [NetworkAdapterInterface] dropping deprecated [NetworkAdapter] inherits. * Update README.md * 1.1.1 * Update NetworkAdapter.test.ts
1 parent 2daf2e4 commit 7d46c85

File tree

7 files changed

+105
-22
lines changed

7 files changed

+105
-22
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ This project adheres to [Semantic Versioning](http://semver.org/).
1111
#### Security
1212

1313

14+
## [1.1.1] - 2024-02-28
15+
#### Added
16+
- onData callback method (replacing the rxjs observable pattern from original implementation).
17+
- Export types from package.
18+
- Converted adapter to implement [NetworkAdapterInterface] as [NetworkAdapter] base abstract class deprecated.
19+
#### Changed
20+
- Rename `WebrtcNetworkAdapter` to `PeerjsNetworkAdapter`
21+
- Version set to `1.1.1` to match main `automerge-repo` version.
22+
23+
1424

1525
## [0.0.1] - 2024-02-27
1626
#### Added

README.md

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,43 @@
1-
[![ci.node](https://github.com/philcockfield/automerge-repo-network-peerjs/actions/workflows/ci.node.yml/badge.svg)](https://github.com/philcockfield/automerge-repo-network-peerjs/actions/workflows/ci.node.yml)
21
# automerge-repo-network-peerjs
2+
[![ci.node](https://github.com/philcockfield/automerge-repo-network-peerjs/actions/workflows/ci.node.yml/badge.svg)](https://github.com/philcockfield/automerge-repo-network-peerjs/actions/workflows/ci.node.yml)
33

44
A network adapter for WebRTC, based on the point-to-point [MessageChannelNetworkAdapter](https://github.com/automerge/automerge-repo/blob/main/packages/automerge-repo-network-messagechannel/src/index.ts).
55

66

77
**Please Note:** This is not an official part of the [automerge-repo](https://github.com/automerge/automerge-repo) project, rather a community contribution that includes a dependency on the [peerjs](https://github.com/peers/peerjs) library.
88

99
## Setup
10-
1110
```
1211
yarn add automerge-repo-network-peerjs
1312
```
1413

15-
## Licence: MIT
14+
## Usage
15+
16+
Establish a data connection as per [peerjs](https://github.com/peers/peerjs#data-connections) documentation:
17+
18+
```ts
19+
import { Peer } from "peerjs";
20+
const conn = peer.connect("another-peers-id");
21+
```
22+
23+
Then use that to pass into the constructor of the automerge network adapter:
24+
25+
```ts
26+
import { PeerjsNetworkAdapter } from 'automerge-repo-network-peerjs';
27+
const adapter = new PeerjsNetworkAdapter(conn);
28+
```
29+
30+
Along with the usual `NetworkAdapterInterface` events an additional `onData` event is available to
31+
to keep track of directional data being sent and received, for example:
32+
33+
```ts
34+
function monitor(adapter: PeerjsNetworkAdapter, dispose$?: Observable<any>) {
35+
const detach = adapter.onData((e) => console.log(`⚡️ ${e.direction}: ${e.bytes} bytes`));
36+
dispose$?.subscribe(() => detach());
37+
}
38+
39+
```
40+
41+
42+
## Licence
43+
MIT

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
{
22
"name": "automerge-repo-network-peerjs",
3-
"version": "0.0.1",
3+
"version": "1.1.1",
44
"description": "Network adapter for automerge-repo using peerjs",
55
"author": "phil Cockfield",
66
"license": "MIT",
77
"type": "module",
88
"main": "dist/index.js",
9+
"types": "dist/index.d.ts",
910
"scripts": {
1011
"build": "tsc",
1112
"test": "vitest"

src/NetworkAdapter.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { describe, expect, it } from "vitest";
22

33
describe("NetworkAdapter", () => {
4+
/**
5+
* NOTE: WebRTC is a browser based technology so server-side testing is hard.
6+
* Over time, if it becomes necessary, we can expand these tests out
7+
* to include mocking.
8+
*/
49
it("placeholder", () => {
510
expect(123).to.eql(123);
611
});

src/NetworkAdapter.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { NetworkAdapter } from "@automerge/automerge-repo";
21
import { EventEmitter } from "eventemitter3";
3-
import type * as t from "./t.js";
2+
import type * as t from "./types.js";
3+
4+
type EventTypes = { data: t.NetworkMessageAlert };
45

56
/**
67
* An Automerge repo network-adapter for WebRTC (P2P)
@@ -10,25 +11,32 @@ import type * as t from "./t.js";
1011
* https://github.com/automerge/automerge-repo/blob/main/packages/automerge-repo-network-messagechannel/src/index.ts
1112
*
1213
*/
13-
export class WebrtcNetworkAdapter extends NetworkAdapter {
14-
#conn: t.DataConnection;
14+
export class PeerjsNetworkAdapter
15+
extends EventEmitter<t.NetworkAdapterEvents>
16+
implements t.NetworkAdapterInterface
17+
{
18+
peerId?: t.PeerId;
19+
peerMetadata?: t.PeerMetadata;
20+
1521
#isReady = false;
16-
#disconnected = new EventEmitter<"disconnected">();
22+
#conn: t.DataConnection;
23+
#events = new EventEmitter<EventTypes>();
1724

1825
constructor(conn: t.DataConnection) {
1926
if (!conn) throw new Error(`A peerjs data-connection is required`);
2027
super();
2128
this.#conn = conn;
2229
}
2330

24-
connect(peerId: t.PeerId) {
31+
connect(peerId: t.PeerId, meta?: t.PeerMetadata) {
2532
const senderId = (this.peerId = peerId);
2633
const conn = this.#conn;
34+
const peerMetadata = meta ?? {};
2735

28-
const handleOpen = () => this.#transmit({ type: "arrive", senderId, peerMetadata: {} });
36+
const handleOpen = () => this.#transmit({ type: "arrive", senderId, peerMetadata });
2937
const handleClose = () => this.emit("close");
3038
const handleData = (e: any) => {
31-
const msg = e as t.WebrtcMessage;
39+
const msg = e as t.NetworkMessage;
3240

3341
/**
3442
* Arrive.
@@ -56,13 +64,14 @@ export class WebrtcNetworkAdapter extends NetworkAdapter {
5664
let payload = msg as t.Message;
5765
if ("data" in msg) payload = { ...payload, data: toUint8Array(msg.data!) };
5866
this.emit("message", payload);
67+
this.#alert("incoming", msg);
5968
};
6069

6170
conn.on("open", handleOpen);
6271
conn.on("close", handleClose);
6372
conn.on("data", handleData);
6473

65-
this.#disconnected.on("disconnected", () => {
74+
this.on("peer-disconnected", () => {
6675
this.#isReady = false;
6776
conn.off("open", handleOpen);
6877
conn.off("close", handleClose);
@@ -78,7 +87,13 @@ export class WebrtcNetworkAdapter extends NetworkAdapter {
7887
}
7988

8089
disconnect() {
81-
this.#disconnected.emit("disconnected");
90+
const peerId = this.peerId;
91+
if (peerId) this.emit("peer-disconnected", { peerId });
92+
}
93+
94+
onData(fn: (e: t.NetworkMessageAlert) => void) {
95+
this.#events.on("data", fn);
96+
return () => this.#events.off("data", fn);
8297
}
8398

8499
send(message: t.RepoMessage) {
@@ -90,9 +105,16 @@ export class WebrtcNetworkAdapter extends NetworkAdapter {
90105
}
91106
}
92107

93-
#transmit(message: t.WebrtcMessage) {
108+
#transmit(message: t.NetworkMessage) {
94109
if (!this.#conn) throw new Error("Connection not ready");
95110
this.#conn.send(message);
111+
this.#alert("outgoing", message);
112+
}
113+
114+
#alert(direction: t.IODirection, message: t.NetworkMessage) {
115+
const bytes = "data" in message ? message.data?.byteLength ?? 0 : 0;
116+
const payload: t.NetworkMessageAlert = { direction, message, bytes };
117+
this.#events.emit("data", payload);
96118
}
97119

98120
#setAsReady() {

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export { WebrtcNetworkAdapter } from "./NetworkAdapter.js";
1+
export { PeerjsNetworkAdapter } from "./NetworkAdapter.js";
2+
export type { NetworkMessage, NetworkMessageAlert } from "./types.js";

src/t.ts renamed to src/types.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
/**
22
* @automerge
33
*/
4-
import type { Message, PeerId, RepoMessage, StorageId } from "@automerge/automerge-repo";
5-
export { Message, PeerId, RepoMessage };
4+
import type {
5+
Message,
6+
NetworkAdapterEvents,
7+
NetworkAdapterInterface,
8+
PeerId,
9+
RepoMessage,
10+
StorageId,
11+
} from "@automerge/automerge-repo";
12+
export type {
13+
Message,
14+
NetworkAdapterEvents,
15+
NetworkAdapterInterface,
16+
PeerId,
17+
RepoMessage,
18+
StorageId,
19+
};
620

721
/**
822
* @peerjs
@@ -15,12 +29,14 @@ export type { DataConnection } from "peerjs";
1529
* MessageChannelNetworkAdapter
1630
* https://github.com/automerge/automerge-repo/blob/main/packages/automerge-repo-network-messagechannel/src/index.ts
1731
*/
18-
export type IODirection = "incoming" | "outgoing";
32+
export type { PeerjsNetworkAdapter } from "./NetworkAdapter.js";
1933

20-
export type WebrtcMessage = ArriveMessage | WelcomeMessage | Message;
21-
export type WebrtcMessageAlert = {
34+
export type IODirection = "incoming" | "outgoing";
35+
export type NetworkMessage = ArriveMessage | WelcomeMessage | Message;
36+
export type NetworkMessageAlert = {
2237
direction: IODirection;
23-
message: WebrtcMessage;
38+
message: NetworkMessage;
39+
bytes: number;
2440
};
2541

2642
/**

0 commit comments

Comments
 (0)