Project y-webxdc

Expand description

y-webxdc

Check API docs Repository

Webxdc applications can be shared in chat with messengers like Delta Chat and Cheogram.

Webxdc applications can support collaborative editing: multiple users, each running their own application instance (a "chat peer") over a shared chat channel all editing the same document, or interacting with the same database.

Synchronizing arbitrary application state is an advanced computer science problem. One popular solution is the conflict-free replicated data type, or CRDT for short.

Yjs is a JavaScript library that implements CRDT for JavaScript data structures such as text, arrays and maps.

This library, y-webxdc, provides an integration of Yjs with Webxdc. It tries to make building collaborative live editing more approachable for Webxdc. It ensures that updates to your application's state are distributed to other chat peers of that same application in a shared chat channel.

  • You use Yjs shared data types for your application state, and WebxdcProvider in this lib makes it work with Webxdc.

  • You can also use Yjs awareness to share ephemeral awareness and presence information (such as user status information, cursor locations, etc).

  • Receiving updates to application state from chat peers.

  • Autosave: automatically send application state changes periodically to chat peers.

  • Manual save: call syncToChatPeers() to cause an immediate save (it's fine to mix manual with autosave).

  • Realtime support: by using a protocol that supports realtime, apps can send and receive application updates as well as awareness information more quickly.

  • Control which metadata is shown in a chat by setting document, summary and chat-message information (see the screenshots below).

  • Reliably save any pending application state changes when the app window closes, on all webxdc-supporting platforms.

Webxdc is inherently an unreliable channel, so messages can get lost and be reordered. We support different protocols in which applications transmit state, each with different trade-offs. We list the most important protocols here.

We are working on new protocols that ensure applications stay in sync yet also send small updates.

The default protocol, sendAllProtocol, forces consistency over unreliable message delivery by sending the entire application state sent every update. Incoming state is merged into the local state using yjs.

This guarantees that application instances synchronize eventually, but also means that if application state gets large, the update messages may become unwieldy.

This protocol was the previous default behavior of y-webxdc before version 1.3.0. Only the edits are sent over the network, meaning that the update messages do not become large. But the major drawback is that if an update message is lost, applications can become permanently desynchronized.

This protocol has the behavior of sendAllProtocol, sending the source of truth as regular webxdc updates. In addition, it sends information over the realtime channel as well if this channel is available. The information it sends over the realtime channel consists of incremental updates (using incrementalProtocol) as well as awareness/presence information.

Because it behaves like sendAllProtocol, this protocol guarantees application instances stay in sync, but also shares it drawback of potential update messages of unwieldy size.

npm i y-webxdc

For a complete overview of the API, see API docs.

import * as Y from "yjs";
import { WebxdcProvider } from "y-webxdc";

// provided by messengers or webxdc-dev tool
// see https://docs.webxdc.org/spec.html
const webxdc = window.webxdc;

const ydoc = new Y.Doc();
const yarray = ydoc.get("array", Y.Array);
const provider = new WebxdcProvider({
webxdc,
ydoc,
getEditInfo: () => {
const document = "webxdc yjs provider";
const summary = `Last edit: ${webxdc.selfName}`;
const startinfo = `${webxdc.selfName} editing ${document}`;
return { document, summary, startinfo };
},
});

See the following example for the meaning of document, summary and startinfo as returned by the getEditInfo callback passed into the provider.

The webxdc editor uses y-webxdc to implement a collaborative editor.

Editor running Delta Chat desktop

Showing edit information in chat

This project is written in TypeScript and uses pnpm. Install dependencies with:

pnpm install

Run the test suite (vitest):

pnpm test

Compile src/ to dist/ (JavaScript plus type declarations):

pnpm build

Check types without emitting any output:

pnpm typecheck

Linting with eslint and formatting with prettier:

pnpm lint
pnpm lint:fix
pnpm format

pnpm lint:fix applies eslint fixes; pnpm format reformats with prettier.

pnpm check runs the formatting check, the type checker, the linter and the tests together:

pnpm check

Type Aliases§

Payload

The status-update payload exchanged between peers.

WebxdcTransport

The subset of Webxdc this provider uses. Pass your full window.webxdc here.

Variables§

awarenessItemCodec

This codec encodes Webxdc awareness entries (as a webxdc update).

updateItemCodec

This codec encodes Webxdc update log entries.

Functions§

incrementalProtocol

Send only what changed to the local yjs document on every webxdc autosave tick.

realtimeProtocol

A protocol with a realtime accelerator channel.

sendAllProtocol

Sends the whole document state on every webxdc autosave tick.

sendAllWithAwarenessProtocol

A protocol that also sends awareness information with the webxdc update.

Classes§

AwarenessStrategy

Convenience base class for strategies.

BaseStrategy

Convenience base class for strategies.

IncrementalStrategy

Send only the data of each local edit.

OutgoingBuffer

An outgoing buffer that stages items until the next flush.

Protocol

The protocol the provider runs.

SendAllStrategy

Send the entire document state whenever there was a local edit.

WebxdcProvider

Webxdc integration with yjs.

Interfaces§

AwarenessItem

Items sent between peers can be distinguished by type.

EditInfo

Display metadata for an edit, shown in the chat.

Item

Items sent between peers can be distinguished by type.

SyncContext

Content the strategy acts on.

SyncStrategy

A sync strategy that handles a single item type: handle incoming items, determine what items to send.

UpdateItem

An update item carries yjs update data for the receiver to apply.

WebxdcProviderOptions

Configuration for WebxdcProvider.

WebxdcUpdateItemCodec

The webxdc update log wants JSON.