Hone logo
Hone
Problems

Collaborative Text Editor in React with TypeScript

This challenge focuses on building a simplified collaborative text editor using React and TypeScript. Collaborative editing allows multiple users to simultaneously view and modify the same document, and this exercise will explore the fundamental concepts of synchronizing changes in real-time. The goal is to create a basic editor where changes made by one user are reflected in the editor of other connected users.

Problem Description

You are tasked with building a React component that implements a collaborative text editor. The editor should allow users to type text, and any changes made by one user should be immediately reflected in the editors of all other connected users. This will be achieved using a simple WebSocket connection for real-time communication.

What needs to be achieved:

  • A React component displaying a text area.
  • A WebSocket connection to a simulated server (details provided in Notes).
  • Real-time synchronization of text changes between connected clients.
  • A simple UI to indicate connection status.

Key Requirements:

  • TypeScript: The entire solution must be written in TypeScript.
  • React: Utilize React components for the UI.
  • WebSocket: Use WebSockets for real-time communication. You will not need to implement the server; a simple mock server is provided (see Notes).
  • State Management: Manage the editor's text content using React state.
  • Error Handling: Implement basic error handling for WebSocket connections.

Expected Behavior:

  1. When the component mounts, it should attempt to connect to the WebSocket server.
  2. The UI should display a "Connecting..." message until the connection is established.
  3. Once connected, the UI should display a "Connected" message.
  4. As the user types in the text area, the changes should be immediately sent to the server.
  5. The server should broadcast these changes to all connected clients.
  6. Other connected clients should receive the updates and update their text area accordingly.
  7. If the WebSocket connection is lost, the UI should display an "Disconnected" message and attempt to reconnect.

Edge Cases to Consider:

  • Handling disconnections and reconnections gracefully.
  • Dealing with potential race conditions when multiple users are typing simultaneously (a simple approach is sufficient – last write wins).
  • Ensuring the UI remains responsive even with frequent updates.
  • What happens if the server goes down?

Examples

Example 1:

Input: User A types "Hello" into the editor. User B is also connected and viewing the same editor.
Output: User B's editor displays "Hello".
Explanation: User A's change is sent to the server, which broadcasts it to all connected clients, including User B.

Example 2:

Input: User A types "Hello" then deletes "lo", resulting in "Hel". User B is connected.
Output: User B's editor displays "Hel".
Explanation: Each keystroke/deletion is sent to the server and broadcast to all connected clients.

Example 3:

Input: The WebSocket connection is lost.
Output: The UI displays "Disconnected" and attempts to reconnect. The editor freezes until reconnection is successful.
Explanation: The component handles the WebSocket close event and attempts to re-establish the connection.

Constraints

  • WebSocket URL: The WebSocket server URL is fixed at ws://localhost:8080.
  • Server Implementation: You are not required to implement the server. A mock server is provided in the Notes section. Focus solely on the client-side React component.
  • Performance: The solution should be reasonably performant. Avoid unnecessary re-renders. Optimizations beyond basic React best practices are not required.
  • Complexity: Keep the solution relatively simple. Focus on the core functionality of collaborative editing. Advanced features like cursor positioning, user identification, or rich text formatting are out of scope.
  • Text Length: The maximum length of the text in the editor should be limited to 500 characters.

Notes

  • Mock Server: A simple mock WebSocket server can be implemented using Node.js and the ws library. This server simply broadcasts any received message to all connected clients. You can find many examples online by searching for "Node.js WebSocket echo server". For testing purposes, you can use a tool like Postman to simulate multiple clients connecting to the server.
  • Libraries: You are free to use any standard React libraries (e.g., useState, useEffect). External UI libraries (e.g., Material UI, Bootstrap) are not required but can be used if desired.
  • Error Handling: Implement basic error handling for WebSocket connection errors. More sophisticated error handling is not required.
  • Focus on the Client: The primary focus is on the React component's behavior and its interaction with the WebSocket server. The server's implementation is assumed to be functional.
  • Reconnect Logic: Implement a simple reconnect mechanism with a delay (e.g., 5 seconds) between reconnection attempts.
  • Initial State: The initial text content of the editor should be an empty string.
  • Data Format: The data sent over the WebSocket should be a simple string representing the current text content.
Loading editor...
typescript