From a628ff348edaa7b3cc38074ba0840f82479afe69 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 7 Jun 2025 11:32:20 +0100 Subject: [PATCH] Send spans instead of indexes --- .../src/app_state/websocket/models.rs | 11 ++++++++-- backend/sync_server/src/server/websocket.rs | 20 +++++++++---------- .../src/services/types/ClientCursors.ts | 3 ++- .../types/CursorPositionFromClient.ts | 3 ++- .../src/services/types/CursorSpan.ts | 3 +++ scripts/update-api-types.sh | 4 ++-- 6 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 frontend/sync-client/src/services/types/CursorSpan.ts diff --git a/backend/sync_server/src/app_state/websocket/models.rs b/backend/sync_server/src/app_state/websocket/models.rs index e6b1bade..0b8e1828 100644 --- a/backend/sync_server/src/app_state/websocket/models.rs +++ b/backend/sync_server/src/app_state/websocket/models.rs @@ -15,17 +15,24 @@ pub struct WebSocketHandshake { pub last_seen_vault_update_id: Option, } +#[derive(TS, Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct CursorSpan { + pub start: usize, + pub end: usize, +} + #[derive(TS, Deserialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct CursorPositionFromClient { - pub document_to_cursors: HashMap>, + pub document_to_cursors: HashMap>, } #[derive(TS, Serialize, Clone, Debug)] #[serde(rename_all = "camelCase")] pub struct ClientCursors { pub device_id: DeviceId, - pub cursors: HashMap>, + pub cursors: HashMap>, } #[derive(TS, Serialize, Clone, Debug)] diff --git a/backend/sync_server/src/server/websocket.rs b/backend/sync_server/src/server/websocket.rs index ea0e7fad..822c211c 100644 --- a/backend/sync_server/src/server/websocket.rs +++ b/backend/sync_server/src/server/websocket.rs @@ -59,9 +59,9 @@ async fn websocket( stream: WebSocket, vault_id: VaultId, ) -> Result<(), SyncServerError> { - let (mut sender, mut receiver) = stream.split(); + let (mut sender, mut websocket_receiver) = stream.split(); - let handshake = if let Some(Ok(message)) = receiver.next().await { + let handshake = if let Some(Ok(message)) = websocket_receiver.next().await { get_handshake(&state, &vault_id, message)? } else { return Err(unauthenticated_error(anyhow::anyhow!( @@ -69,7 +69,7 @@ async fn websocket( ))); }; - let mut rx = state.broadcasts.get_receiver(vault_id.clone()).await; + let mut broadcast_receiver = state.broadcasts.get_receiver(vault_id.clone()).await; send_update_over_websocket( &WebSocketServerMessage::VaultUpdate(WebSocketVaultUpdate { @@ -91,7 +91,7 @@ async fn websocket( let device_id = handshake.device_id.clone(); let mut send_task = tokio::spawn(async move { - while let Ok(update) = rx.recv().await { + while let Ok(update) = broadcast_receiver.recv().await { if Some(&device_id) == update.origin_device_id.as_ref() { continue; } @@ -103,10 +103,10 @@ async fn websocket( }); let device_id = handshake.device_id.clone(); - let mut recv_task = tokio::spawn(async move { - while let Some(Ok(Message::Text(message))) = receiver.next().await { + let mut receive_task = tokio::spawn(async move { + while let Some(Ok(Message::Text(message))) = websocket_receiver.next().await { let message: WebSocketClientMessage = serde_json::from_str(&message) - .context("Failed to parse message") + .context("Failed to parse WebSocket message from client") .map_err(server_error)?; match message { @@ -128,8 +128,8 @@ async fn websocket( }); tokio::select! { - _ = &mut send_task => recv_task.abort(), - _ = &mut recv_task => send_task.abort(), + _ = &mut send_task => receive_task.abort(), + _ = &mut receive_task => send_task.abort(), }; send_task @@ -137,7 +137,7 @@ async fn websocket( .context("WebSocket send task failed") .map_err(server_error)??; - recv_task + receive_task .await .context("WebSocket receive task failed") .map_err(server_error)??; diff --git a/frontend/sync-client/src/services/types/ClientCursors.ts b/frontend/sync-client/src/services/types/ClientCursors.ts index 4a91a1e7..87ebebdf 100644 --- a/frontend/sync-client/src/services/types/ClientCursors.ts +++ b/frontend/sync-client/src/services/types/ClientCursors.ts @@ -1,3 +1,4 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { CursorSpan } from "./CursorSpan"; -export type ClientCursors = { deviceId: string, cursors: { [key in string]?: Array }, }; +export type ClientCursors = { deviceId: string, cursors: { [key in string]?: Array }, }; diff --git a/frontend/sync-client/src/services/types/CursorPositionFromClient.ts b/frontend/sync-client/src/services/types/CursorPositionFromClient.ts index 5a60ec2f..87705d1c 100644 --- a/frontend/sync-client/src/services/types/CursorPositionFromClient.ts +++ b/frontend/sync-client/src/services/types/CursorPositionFromClient.ts @@ -1,3 +1,4 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { CursorSpan } from "./CursorSpan"; -export type CursorPositionFromClient = { documentToCursors: { [key in string]?: Array }, }; +export type CursorPositionFromClient = { documentToCursors: { [key in string]?: Array }, }; diff --git a/frontend/sync-client/src/services/types/CursorSpan.ts b/frontend/sync-client/src/services/types/CursorSpan.ts new file mode 100644 index 00000000..916019ce --- /dev/null +++ b/frontend/sync-client/src/services/types/CursorSpan.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type CursorSpan = { start: number; end: number }; diff --git a/scripts/update-api-types.sh b/scripts/update-api-types.sh index 6fc7f6cd..3c8f788b 100755 --- a/scripts/update-api-types.sh +++ b/scripts/update-api-types.sh @@ -2,8 +2,6 @@ set -e -./scripts/utils/wait-for-server.sh - rm -rf backend/sync_server/bindings cd backend cargo test export_bindings @@ -11,5 +9,7 @@ cd - cp -r backend/sync_server/bindings/* frontend/sync-client/src/services/types/ +./scripts/utils/wait-for-server.sh + npm install -g openapi-typescript openapi-typescript http://localhost:3000/api.json --output frontend/sync-client/src/services/types/http-api.ts