mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 18:34:03 +03:00
d9972d547a
Fixes #10197 # Important Notes From now on, package installation will be using `pnpm install`. Installing it globally is fine for convenience, but it can also be used as `corepack pnpm install` without having to install anything other than node. For now, all other scripts are still invoked using `npm`, so we can still invoke them with usual `--workspace` setting. As far as I can tell that doesn't really have any other side effects and is identical as running the script through `pnpm run` in respective workspace project subdirectory.
73 lines
2.5 KiB
TypeScript
73 lines
2.5 KiB
TypeScript
/**
|
|
* @file An entry point for the Yjs gateway server. The gateway server is a WebSocket server that
|
|
* synchronizes document requests and updates between language server and clients connected to the
|
|
* Yjs document mesh. It also serves as a central point for synchronizing document data and
|
|
* awareness updates between clients.
|
|
*
|
|
* Currently, this server is being run automatically in background as part of the vite development
|
|
* server. It is not yet deployed to any other environment.
|
|
*/
|
|
|
|
import type { Server } from 'http'
|
|
import type { Http2SecureServer } from 'http2'
|
|
import { IncomingMessage } from 'node:http'
|
|
import { parse } from 'url'
|
|
import { WebSocket, WebSocketServer } from 'ws'
|
|
import { initializeFFI } from '../shared/ast/ffi'
|
|
import { ConnectionData, docName } from './auth'
|
|
import { setupGatewayClient } from './ydoc'
|
|
|
|
export async function createGatewayServer(
|
|
httpServer: Server | Http2SecureServer,
|
|
rustFFIPath: string | undefined,
|
|
) {
|
|
await initializeFFI(rustFFIPath)
|
|
const wss = new WebSocketServer({ noServer: true })
|
|
wss.on('connection', (ws: WebSocket, _request: IncomingMessage, data: ConnectionData) => {
|
|
ws.on('error', onWebSocketError)
|
|
setupGatewayClient(ws, data.lsUrl, data.doc)
|
|
})
|
|
|
|
httpServer.on('upgrade', (request, socket, head) => {
|
|
socket.on('error', onHttpSocketError)
|
|
authenticate(request, function next(err, data) {
|
|
if (err != null) {
|
|
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n')
|
|
socket.destroy()
|
|
return
|
|
}
|
|
socket.removeListener('error', onHttpSocketError)
|
|
if (data != null) {
|
|
wss.handleUpgrade(request, socket, head, function done(ws) {
|
|
wss.emit('connection', ws, request, data)
|
|
})
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
function onWebSocketError(err: Error) {
|
|
console.log('WebSocket error:', err)
|
|
}
|
|
|
|
function onHttpSocketError(err: Error) {
|
|
console.log('HTTP socket error:', err)
|
|
}
|
|
|
|
function authenticate(
|
|
request: IncomingMessage,
|
|
callback: (err: Error | null, authData: ConnectionData | null) => void,
|
|
) {
|
|
// FIXME: Stub. We don't implement authentication for now. Need to be implemented in combination
|
|
// with the language server.
|
|
const user = 'mock-user'
|
|
|
|
if (request.url == null) return callback(null, null)
|
|
const { pathname, query } = parse(request.url, true)
|
|
if (pathname == null) return callback(null, null)
|
|
const doc = docName(pathname)
|
|
const lsUrl = query.ls
|
|
const data = doc != null && typeof lsUrl === 'string' ? { lsUrl, doc, user } : null
|
|
callback(null, data)
|
|
}
|