Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove adapter-specific message types from automerge-repo #214

Merged
merged 4 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions packages/automerge-repo-network-broadcastchannel/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@
*
*/

import {
Message,
NetworkAdapter,
PeerId,
RepoMessage,
} from "@automerge/automerge-repo"
import { Message, NetworkAdapter, PeerId } from "@automerge/automerge-repo"

export type BroadcastChannelNetworkAdapterOptions = {
channelName: string
Expand All @@ -41,7 +36,7 @@ export class BroadcastChannelNetworkAdapter extends NetworkAdapter {

this.#broadcastChannel.addEventListener(
"message",
(e: { data: Message }) => {
(e: { data: BroadcastChannelMessage }) => {
const message = e.data
if ("targetId" in message && message.targetId !== this.peerId) {
return
Expand Down Expand Up @@ -87,7 +82,7 @@ export class BroadcastChannelNetworkAdapter extends NetworkAdapter {
this.emit("peer-candidate", { peerId })
}

send(message: RepoMessage) {
send(message: Message) {
if ("data" in message) {
this.#broadcastChannel.postMessage({
...message,
Expand All @@ -106,3 +101,27 @@ export class BroadcastChannelNetworkAdapter extends NetworkAdapter {
throw new Error("Unimplemented: leave on BroadcastChannelNetworkAdapter")
}
}

/** Notify the network that we have arrived so everyone knows our peer ID */
type ArriveMessage = {
type: "arrive"

/** The peer ID of the sender of this message */
senderId: PeerId

/** Arrive messages don't have a targetId */
targetId: never
}

/** Respond to an arriving peer with our peer ID */
type WelcomeMessage = {
type: "welcome"

/** The peer ID of the recipient sender this message */
senderId: PeerId

/** The peer ID of the recipient of this message */
targetId: PeerId
}

type BroadcastChannelMessage = ArriveMessage | WelcomeMessage | Message
95 changes: 61 additions & 34 deletions packages/automerge-repo-network-messagechannel/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,42 +41,45 @@ export class MessageChannelNetworkAdapter extends NetworkAdapter {
log("messageport connecting")
this.peerId = peerId
this.messagePortRef.start()
this.messagePortRef.addListener("message", (e: { data: Message }) => {
log("message port received", e.data)

const message = e.data
if ("targetId" in message && message.targetId !== this.peerId) {
throw new Error(
"MessagePortNetwork should never receive messages for a different peer."
)
}

const { senderId, type } = message

switch (type) {
case "arrive":
this.messagePortRef.postMessage({
senderId: this.peerId,
targetId: senderId,
type: "welcome",
})
this.announceConnection(senderId)
break
case "welcome":
this.announceConnection(senderId)
break
default:
if (!("data" in message)) {
this.emit("message", message)
} else {
this.emit("message", {
...message,
data: new Uint8Array(message.data),
this.messagePortRef.addListener(
"message",
(e: { data: MessageChannelMessage }) => {
log("message port received", e.data)

const message = e.data
if ("targetId" in message && message.targetId !== this.peerId) {
throw new Error(
"MessagePortNetwork should never receive messages for a different peer."
)
}

const { senderId, type } = message

switch (type) {
case "arrive":
this.messagePortRef.postMessage({
senderId: this.peerId,
targetId: senderId,
type: "welcome",
})
}
break
this.announceConnection(senderId)
break
case "welcome":
this.announceConnection(senderId)
break
default:
if (!("data" in message)) {
this.emit("message", message)
} else {
this.emit("message", {
...message,
data: new Uint8Array(message.data),
})
}
break
}
}
})
)

this.messagePortRef.addListener("close", () => {
this.emit("close")
Expand Down Expand Up @@ -142,3 +145,27 @@ export interface MessageChannelNetworkAdapterConfig {
*/
useWeakRef?: boolean
}

/** Notify the network that we have arrived so everyone knows our peer ID */
type ArriveMessage = {
type: "arrive"

/** The peer ID of the sender of this message */
senderId: PeerId

/** Arrive messages don't have a targetId */
targetId: never
}

/** Respond to an arriving peer with our peer ID */
type WelcomeMessage = {
type: "welcome"

/** The peer ID of the recipient sender this message */
senderId: PeerId

/** The peer ID of the recipient of this message */
targetId: PeerId
}

type MessageChannelMessage = ArriveMessage | WelcomeMessage | Message
8 changes: 4 additions & 4 deletions packages/automerge-repo-network-websocket/src/messages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type RepoMessage, type PeerId } from "@automerge/automerge-repo"
import { ProtocolVersion } from "./protocolVersion.js"
import type { Message, PeerId } from "@automerge/automerge-repo"
import type { ProtocolVersion } from "./protocolVersion.js"

/** The sender is disconnecting */
export type LeaveMessage = {
Expand Down Expand Up @@ -42,7 +42,7 @@ export type ErrorMessage = {
// join/leave

/** A message from the client to the server */
export type FromClientMessage = JoinMessage | LeaveMessage | RepoMessage
export type FromClientMessage = JoinMessage | LeaveMessage | Message

/** A message from the server to the client */
export type FromServerMessage = PeerMessage | ErrorMessage | RepoMessage
export type FromServerMessage = PeerMessage | ErrorMessage | Message
2 changes: 0 additions & 2 deletions packages/automerge-repo/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,12 @@ export type {
PeerDisconnectedPayload,
} from "./network/NetworkAdapter.js"
export type {
ArriveMessage,
DocumentUnavailableMessage,
EphemeralMessage,
Message,
RepoMessage,
RequestMessage,
SyncMessage,
WelcomeMessage,
} from "./network/messages.js"
export type { StorageKey } from "./storage/StorageAdapter.js"
export * from "./types.js"
6 changes: 3 additions & 3 deletions packages/automerge-repo/src/network/NetworkAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventEmitter } from "eventemitter3"
import { PeerId } from "../types.js"
import { RepoMessage } from "./messages.js"
import { Message } from "./messages.js"

/** An interface representing some way to connect to other peers
*
Expand All @@ -22,7 +22,7 @@ export abstract class NetworkAdapter extends EventEmitter<NetworkAdapterEvents>
*
* @argument message - the message to send
*/
abstract send(message: RepoMessage): void
abstract send(message: Message): void

/** Called by the {@link Repo} to disconnect from the network */
abstract disconnect(): void
Expand All @@ -44,7 +44,7 @@ export interface NetworkAdapterEvents {
"peer-disconnected": (payload: PeerDisconnectedPayload) => void

/** Emitted when the network adapter receives a message from a peer */
message: (payload: RepoMessage) => void
message: (payload: Message) => void
}

export interface OpenPayload {
Expand Down
29 changes: 8 additions & 21 deletions packages/automerge-repo/src/network/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,18 @@ export type RequestMessage = {
documentId: DocumentId
}

/** Notify the network that we have arrived so everyone knows our peer ID */
export type ArriveMessage = {
type: "arrive"
/** (anticipating work in progress) */
export type AuthMessage<TPayload = any> = {
type: "auth"

/** The peer ID of the sender of this message */
senderId: PeerId

/** Arrive messages don't have a targetId */
targetId: never
}

/** Respond to an arriving peer with our peer ID */
export type WelcomeMessage = {
type: "welcome"

/** The peer ID of the recipient sender this message */
senderId: PeerId

/** The peer ID of the recipient of this message */
targetId: PeerId

/** The payload of the auth message (up to the specific auth provider) */
payload: TPayload
}

/** These are message types that a {@link NetworkAdapter} surfaces to a {@link Repo}. */
Expand All @@ -116,13 +108,8 @@ export type RepoMessage =
| RequestMessage
| DocumentUnavailableMessage

/** These are all the message types that a {@link NetworkAdapter} might see.
*
* @remarks
* It is not _required_ that a {@link NetworkAdapter} use these types: They are free to use
* whatever message type makes sense for their transport. However, this type is a useful default.
* */
export type Message = RepoMessage | ArriveMessage | WelcomeMessage
/** These are all the message types that a {@link NetworkAdapter} might see. */
export type Message = RepoMessage | AuthMessage

/**
* The contents of a message, without the sender ID or other properties added by the {@link NetworkSubsystem})
Expand Down