Y-Sweet Documentation

repository·main·Indexed 21 days ago

https://github.com/jamsocket/y-sweet

An open-source, realtime CRDT-based document store built on top of Yjs and implemented in Rust using y-crdt. Y-Sweet provides a backend for managing shared document state with S3-compatible persistence, horizontal scaling via a session backend model, and token-based access control. It includes a Rust crate usable as a binary or library, a JavaScript client (@y-sweet/client), a React integration library (@y-sweet/react) with hooks for Yjs types and presence, and a backend SDK (@y-sweet/sdk).

Tokens
27.7K
Snippets
104
Records
140
Agent score
76%

What's inside Y-Sweet

  1. What is y-sweet?

    main

    y-sweet is an open-source server designed for building realtime applications using the Yjs CRDT library. It provides a backend for managing shared document state with built-in persistence and authentication.

    Key capabilities include:

    • Persistence: Saves document data to a network filesystem or S3-compatible storage.
    • Scalability: Supports horizontal scaling using a session backend model.
    • Deployment Flexibility: Can be deployed as a native Linux process or as a WebAssembly (Wasm) module on Cloudflare's edge.
    • Security: Provides document-level access control through the use of client tokens.
    • Performance: Built in Rust using the y-crdt library for high stability and performance.
  2. How access control works in y-sweet

    main

    Y-Sweet uses a token-based access control model to secure collaborative documents:

    1. Server-side Authentication: Your server (e.g., a Next.js Server Component) connects to the y-sweet server using a server token. It requests a specific client token for a particular document.
    2. Token Handover: Your server passes this client token to the client (for example, as props to a React component).
    3. Client Connection: The client uses the client token to connect to the y-sweet document. The client token contains all necessary connection information, so the client does not require additional configuration.

    Server Token Format: A server token combines a URL and a secret key. It can be provided as:

    • A JSON object with url and token keys.
    • A JSONified string of the same object.

    This format allows you to store the server token in a secret store and pass it to your server code via environment variables.

  3. How @y-sweet/react hooks work

    main

    The @y-sweet/react hooks provide access to Yjs data types. Each hook returns a specific Yjs type (e.g., Y.Map, Y.Array, Y.Text).

    Key Behavior:

    • Subscription: Each hook automatically subscribes the React component to changes in that specific Yjs type.
    • Re-renders: By default, any change to the value, or any of its descendants, will trigger a re-render of the component.
    • Yjs Integration: Because the hooks return raw Yjs types, you should refer to the Yjs documentation to understand how to manipulate the returned objects.
  4. Add presence features with `useAwareness` and `usePresence`

    main

    Y-Sweet provides two ways to handle presence (user awareness/metadata):

    1. useAwareness: Returns a raw Yjs awareness object. This is best used when integrating with existing Yjs editor bindings (like CodeMirror) that require an awareness instance.
    2. usePresence and usePresenceSetter: Higher-level React abstractions for general-purpose presence features (e.g., showing mouse cursors or user status).

    Using usePresence and usePresenceSetter

    • usePresence<T>() returns a Map<number, T> where the key is the user ID and the value is the user's presence data.
    • usePresenceSetter<T>() returns a function to update the current user's presence data.
    import { usePresence, usePresenceSetter } from '@y-sweet/react'
    
    type Presence = { x: number; y: number; color: string }
    
    export function Presence() {
      const presence = usePresence<Presence>()
      const setPresence = usePresenceSetter<Presence>()
    
      const updatePresence = (e: React.MouseEvent) => {
        setPresence({
          x: e.clientX,
          y: e.clientY,
          color: 'bg-blue-500',
        })
      }
    
      return (
        <div onMouseMove={updatePresence}>
          {Array.from(presence.entries()).map(([key, value]) => (
            <div key={key} style={{ left: value.x, top: value.y }} />
          ))}
        </div>
      )
    }
  5. Quickstart with create-y-sweet-app

    main

    The fastest way to bootstrap a new Y-Sweet project is by using the create-y-sweet-app CLI tool. This will set up the necessary scaffolding for your application.

    npx create-y-sweet-app@latest
  6. Run a Y-Sweet dev server locally

    main

    The fastest way to run a local Y-Sweet server is using npx. By default, the server runs in-memory and does not persist data to disk.

    To run the server without persistence:

    npx y-sweet@latest serve

    To persist data to a local directory, provide the path as an argument:

    npx y-sweet@latest serve /path/to/data

    To use S3-compatible storage, provide a path starting with s3://. Y-Sweet will use your local AWS credentials from the environment. You can configure these using aws configure or by setting the appropriate environment variables.

  7. Run the Y-Sweet NextJS Demo

    main

    To run the NextJS demo application, you must have a connection string for a running Y-Sweet server. You can obtain a connection string by:

    1. Creating a Y-Sweet service at app.jamsocket.com.
    2. Running your own Y-Sweet server locally.

    Once you have your connection string, follow these steps to start the development server:

    # 1. Install dependencies
    npm install
    
    # 2. Start the dev server with your connection string
    CONNECTION_STRING=<your-connection-string> npm run dev