@hocuspocus/server
Advanced tools
Comparing version 2.0.0-alpha.0 to 2.0.0-alpha.1
@@ -90,2 +90,3 @@ import * as Y from 'yjs'; | ||
get isAuthenticationRequired(): boolean; | ||
connect(): Promise<unknown>; | ||
disconnect(): void; | ||
@@ -92,0 +93,0 @@ onOpen(event: Event): Promise<void>; |
@@ -18,3 +18,4 @@ import { Awareness } from 'y-protocols/awareness'; | ||
QueryAwareness = 3, | ||
Stateless = 5 | ||
Stateless = 5, | ||
CLOSE = 7 | ||
} | ||
@@ -21,0 +22,0 @@ export declare enum WebSocketStatus { |
@@ -26,6 +26,10 @@ /// <reference types="node" /> | ||
constructor(connection: WebSocket, request: HTTPIncomingMessage, document: Document, timeout: number, socketId: string, context: any, readOnly: boolean | undefined, logger: Debugger); | ||
boundClose: (event?: CloseEvent | undefined) => void; | ||
boundHandleMessage: (data: Uint8Array) => void; | ||
boundHandlePong: () => void; | ||
handlePong(): void; | ||
/** | ||
* Set a callback that will be triggered when the connection is closed | ||
*/ | ||
onClose(callback: (document: Document) => void): Connection; | ||
onClose(callback: (document: Document, event?: CloseEvent) => void): Connection; | ||
/** | ||
@@ -32,0 +36,0 @@ * Set a callback that will be triggered when an stateless message is received |
@@ -16,3 +16,4 @@ /// <reference types="node" /> | ||
Stateless = 5, | ||
BroadcastStateless = 6 | ||
BroadcastStateless = 6, | ||
CLOSE = 7 | ||
} | ||
@@ -19,0 +20,0 @@ export interface AwarenessUpdate { |
{ | ||
"name": "@hocuspocus/server", | ||
"description": "plug & play collaboration backend", | ||
"version": "2.0.0-alpha.0", | ||
"version": "2.0.0-alpha.1", | ||
"homepage": "https://hocuspocus.dev", | ||
@@ -31,3 +31,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@hocuspocus/common": "^2.0.0-alpha.0", | ||
"@hocuspocus/common": "^2.0.0-alpha.1", | ||
"@types/async-lock": "^1.1.3", | ||
@@ -34,0 +34,0 @@ "@types/uuid": "^9.0.0", |
@@ -31,3 +31,3 @@ import { IncomingMessage as HTTPIncomingMessage } from 'http' | ||
callbacks: any = { | ||
onClose: (document: Document) => null, | ||
onClose: [(document: Document, event?: CloseEvent) => null], | ||
beforeHandleMessage: (document: Document, update: Uint8Array) => Promise, | ||
@@ -74,5 +74,5 @@ statelessCallback: () => Promise, | ||
this.webSocket.on('close', this.close.bind(this)) | ||
this.webSocket.on('message', this.handleMessage.bind(this)) | ||
this.webSocket.on('pong', () => { this.pongReceived = true }) | ||
this.webSocket.on('close', this.boundClose) | ||
this.webSocket.on('message', this.boundHandleMessage) | ||
this.webSocket.on('pong', this.boundHandlePong) | ||
@@ -82,7 +82,17 @@ this.sendCurrentAwareness() | ||
boundClose = this.close.bind(this) | ||
boundHandleMessage = this.handleMessage.bind(this) | ||
boundHandlePong = this.handlePong.bind(this) | ||
handlePong() { | ||
this.pongReceived = true | ||
} | ||
/** | ||
* Set a callback that will be triggered when the connection is closed | ||
*/ | ||
onClose(callback: (document: Document) => void): Connection { | ||
this.callbacks.onClose = callback | ||
onClose(callback: (document: Document, event?: CloseEvent) => void): Connection { | ||
this.callbacks.onClose.push(callback) | ||
@@ -159,4 +169,9 @@ return this | ||
this.document.removeConnection(this) | ||
this.callbacks.onClose(this.document) | ||
this.webSocket.close(event?.code, event?.reason) | ||
clearInterval(this.pingInterval) | ||
this.webSocket.removeListener('close', this.boundClose) | ||
this.webSocket.removeListener('message', this.boundHandleMessage) | ||
this.webSocket.removeListener('pong', this.boundHandlePong) | ||
this.callbacks.onClose.forEach((callback: (arg0: Document, arg1?: CloseEvent) => any) => callback(this.document, event)) | ||
} | ||
@@ -163,0 +178,0 @@ |
@@ -409,2 +409,5 @@ import { createServer, IncomingMessage, Server as HTTPServer } from 'http' | ||
// While the connection is establishing | ||
const connectionEstablishing: Record<string, boolean> = {} | ||
// Once all hooks are run, we’ll fully establish the connection: | ||
@@ -417,4 +420,14 @@ const setUpNewConnection = async (documentName: string) => { | ||
const document = await this.createDocument(documentName, request, socketId, connection, context) | ||
this.createConnection(incoming, request, document, socketId, connection.readOnly, context) | ||
const instance = this.createConnection(incoming, request, document, socketId, connection.readOnly, context) | ||
instance.onClose((document, event) => { | ||
delete documentConnections[documentName] | ||
delete incomingMessageQueue[documentName] | ||
delete connectionEstablishing[documentName] | ||
if (Object.keys(documentConnections).length === 0) { | ||
instance.webSocket.close(event?.code, event?.reason) // TODO: Move this to Hocuspocus connection handler | ||
} | ||
}) | ||
documentConnections[documentName] = true | ||
@@ -440,3 +453,5 @@ | ||
// Okay, we’ve got the authentication message we’re waiting for: | ||
if (type === MessageType.Auth) { | ||
if (type === MessageType.Auth && !connectionEstablishing[documentName]) { | ||
connectionEstablishing[documentName] = true | ||
// The 2nd integer contains the submessage type | ||
@@ -532,5 +547,6 @@ // which will always be authentication when sent from client -> server | ||
// Authentication is required, we’ll need to wait for the Authentication message. | ||
if (connection.requiresAuthentication) { | ||
if (connection.requiresAuthentication || connectionEstablishing[documentName]) { | ||
return | ||
} | ||
connectionEstablishing[documentName] = true | ||
@@ -537,0 +553,0 @@ return setUpNewConnection(documentName) |
@@ -85,3 +85,9 @@ import { | ||
}) | ||
break | ||
case MessageType.CLOSE: | ||
connection?.close({ | ||
code: 1000, | ||
reason: 'provider_initiated', | ||
}) | ||
break | ||
@@ -88,0 +94,0 @@ |
@@ -19,2 +19,4 @@ import { | ||
BroadcastStateless = 6, | ||
CLOSE = 7, | ||
} | ||
@@ -21,0 +23,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
721771
134
8674