y-crossws
TypeScript icon, indicating that this package has built-in type declarations

0.0.2 • Public • Published

y-crossws

npm version npm downloads

yjs websocket server powered by crossws, works with Node.js, Deno, Bun, Cloudflare Workers and more without any framework dependency and compatible with unmodified y-websocket client provider.

[!IMPORTANT] 🚧 This is still a work in progress. Feedback and contributions are welcome!

🍿 Demo

tiptap editor with collaborative editing deployed on Cloudflare workers with durable objects.

Usage

We first need to initiate universal cross-hooks:

import { createHandler } from "y-crossws";

const crosswsHandler = createHandler();

Depending on your server choice, use any of the crossws supported adapters.

Node.js

import { createServer } from "node:http";
import { createHandler } from "y-crossws";
import crossws from "crossws/adapters/node";

const server = createServer((req, res) => {
  res.statusCode = 426;
  res.end("");
});

const ws = crossws(createHandler());

server.on("upgrade", ws.handleUpgrade);

server.listen(3000);

[!NOTE] Read more about Node.js adapter in crossws docs.

Bun

import { createHandler } from "y-crossws";
import crossws from "crossws/adapters/bun";

const ws = crossws(createHandler());

Bun.serve({
  port: 3000,
  websocket: ws.websocket,
  fetch(req, server) {
    if (request.headers.get("upgrade") === "websocket") {
      return ws.handleUpgrade(request, server);
    }
    return new Response("", { status: 426 });
  },
});

[!NOTE] Read more about Bun adapter in crossws docs.

Deno

import { createHandler } from "y-crossws";
import crossws from "crossws/adapters/deno";

const ws = crossws(createHandler());

Deno.serve({ port: 3000 }, (request, info) => {
  if (request.headers.get("upgrade") === "websocket") {
    return ws.handleUpgrade(request, server);
  }
  return new Response("", { status: 426 });
});

[!NOTE] Read more about Deno adapter in crossws docs.

Cloudflare (with durable objects)

import { createHandler } from "y-crossws";
import { DurableObject } from "cloudflare:workers";
import crossws from "crossws/adapters/cloudflare-durable";

const ws = crossws(createHandler());

export default {
  async fetch(request, env, context) {
    if (request.headers.get("upgrade") === "websocket") {
      return ws.handleUpgrade(request, env, context);
    }
    return new Response("", { status: 426 });
  },
};

export class $DurableObject extends DurableObject {
  fetch(request) {
    return ws.handleDurableUpgrade(this, request);
  }
  webSocketMessage(client, message) {
    return ws.handleDurableMessage(this, client, message);
  }
  webSocketClose(client, code, reason, wasClean) {
    return ws.handleDurableClose(this, client, code, reason, wasClean);
  }
}

Update your wrangler.toml config to specify Durable object:

durable_objects.bindings = [
  { name = "$DurableObject", class_name = "$DurableObject" }
]

migrations = [
  { tag = "v1", new_classes = ["$DurableObject"] }
]

[!NOTE] Read more about Cloudflare adapter in crossws docs.

Websocket provider

You can use WebsocketProvider from legacy y-websocket or a native one from y-crossws. Both are almost identical in terms of API at the moment, however, the y-crossws version has better typescript refactors and might introduce more enhancements in sync with the server provider in the future.

import * as Y from "yjs";
import { WebsocketProvider } from "y-crossws/provider";

const ydoc = new Y.Doc();
const roomName = "default";

const wsProto = window.location.protocol === "https:" ? "wss:" : "ws:";
const wsUrl = `${wsProto}://${window.location.host}/_ws`;

const provider = new WebsocketProvider(wsURL, roomName, ydoc, {
  /* options */
});

Provider options

  • params: URL parameters to append.
  • protocols: Specify websocket protocols.
  • WebSocketPolyfill: WebSocket polyfill.
  • maxBackoffTime: Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential (default 2500).
  • resyncInterval: Request server state every resyncInterval milliseconds (default -1).
  • connect: Whether to connect to other peers or not (default: true).
  • awareness: Awareness instance.
  • disableBc: Disable cross-tab BroadcastChannel communication (default: false).

Development

local development
  • Clone this repository
  • Install the latest LTS version of Node.js
  • Enable Corepack using corepack enable
  • Install dependencies using pnpm install
  • Build in stub mode using pnpm build --stub
  • Run playgrounds with pnpm dev:* commands.

License

💛 Published under the MIT license.

Package Sidebar

Install

npm i y-crossws

Weekly Downloads

4

Version

0.0.2

License

MIT

Unpacked Size

33.6 kB

Total Files

9

Last publish

Collaborators

  • pi0