hedgedoc/commons/src/websocket-transporter.ts
Tilman Vatteroth 7320fe2ac1 feat(packages): add commons package
This is an import of 166ca8da12
with some changes to make it fit into the mono repo.
- TypedEventEmitter has been replaced with EventEmitter2 because EventEmitter2 is faster and TypedEventEmitter had some troubles with the new way of compiling.
- tsc-esm has been replaced with microbundle. The problems that lib0 doesn't export its types correctly has been solved using yarn patch.

Signed-off-by: Tilman Vatteroth <git@tilmanvatteroth.de>
2022-12-11 23:09:10 +01:00

61 lines
1.7 KiB
TypeScript

/*
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { ConnectionKeepAliveHandler } from './connection-keep-alive-handler.js'
import { YDocMessageTransporter } from './y-doc-message-transporter.js'
import WebSocket from 'isomorphic-ws'
import { Awareness } from 'y-protocols/awareness'
import { Doc } from 'yjs'
export class WebsocketTransporter extends YDocMessageTransporter {
private websocket: WebSocket | undefined
constructor(doc: Doc, awareness: Awareness) {
super(doc, awareness)
new ConnectionKeepAliveHandler(this)
}
public setupWebsocket(websocket: WebSocket) {
if (
websocket.readyState === WebSocket.CLOSED ||
websocket.readyState === WebSocket.CLOSING
) {
throw new Error(`Socket is closed`)
}
this.websocket = websocket
websocket.binaryType = 'arraybuffer'
websocket.addEventListener('message', (event) =>
this.decodeMessage(event.data as ArrayBuffer)
)
websocket.addEventListener('error', () => this.disconnect())
websocket.addEventListener('close', () => this.onClose())
if (websocket.readyState === WebSocket.OPEN) {
this.onOpen()
} else {
websocket.addEventListener('open', this.onOpen.bind(this))
}
}
public disconnect(): void {
this.websocket?.close()
}
public send(content: Uint8Array): void {
if (this.websocket?.readyState !== WebSocket.OPEN) {
throw new Error("Can't send message over non-open socket")
}
try {
this.websocket.send(content)
} catch (error: unknown) {
this.disconnect()
throw error
}
}
public isWebSocketOpen(): boolean {
return this.websocket?.readyState === WebSocket.OPEN
}
}