1.1.0 • Published 1 year ago

codelabs.y-socket.io v1.1.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

Socket IO Connector for Yjs (Inspired by y-websocket)

Y-socket.io is a YJS document synchronization implementation over the websockets protocol inspired by y-websocket, but implemented with Socket.io. So for YJS and Socket.io enthusiasts it could be a simple and scalable alternative.

Like y-websocket, this is a solid option if you want to manage authentication and authorization for editing YJS documents at a single point.

Y-socket.io features:

  • Configuration and customization of the server side.
  • Easy implementation of your authentication.
  • Ability to enable document persistence with LevelDB.
  • Ability to add custom callbacks at different points in a document's life cycle as shown below.
  • Cross-tab communication, i.e. when opening the same document in more than one tab, changes are also transmitted via cross-tab communication (broadcast channel and localstorage as an alternative).
  • Awareness information exchange.

IMPORTANT: Y-socket.io does not have HTTP callbacks implemented, because as mentioned above, you can implement custom callbacks (in the document update callback you could implement your HTTP callback logic).

Installation

To install you can run this command

npm i y-socket.io

Usage

Server side

You can run a basic server (you can review the source code here) using:

HOST=localhost PORT=1234 npx y-socket-io

(by default the server listens on localhost:1234)

Although this server is functional, I recommend reviewing the example to extend it, add your own logic (such as authentication, document callbacks, etc.), and adapt it to your use case.

Adding y-socket.io to your project

Y-socket.io is very easy to add an new or existent project with socket.io. You just need to pass the socket.io server instance as shown below:

import { YSocketIO } from 'y-socket.io/dist/server'

// Create the YSocketIO instance
// NOTE: This uses the socket namespaces that match the regular expression /^\/yjs\|.*$/ 
//       (for example: 'ws://localhost:1234/yjs|my-document-room'), make sure that when using namespaces
//       for other logic, these do not match the regular expression, this could cause unwanted problems.
// TIP: You can export a new instance from another file to manage as singleton and access documents from all app.
const ysocketio = new YSocketIO(io)
// Execute initialize method
ysocketio.initialize()

You can also pass an object with the settings you need for your implementation. You can see the available options in the Server API

Client side

You can use SocketIOProvider on your client side like this:

import * as Y from 'yjs'
import { SocketIOProvider } from 'y-socket.io'

const doc = new Y.Doc()
const provider = new SocketIOProvider('ws://localhost:1234', 'room-name', doc);

provider.on('status', ({ status }: { status: string }) => {
  console.log(status) // Logs "connected" or "disconnected"
})

As with the server-side instance, in the SocketIOProvider you can also pass a number of parameters to configure your implementation. You can see the available options in the Client API

(Here you can review an example in ReactJS)

Run examples

This repository has an example that you can run in your machine and play with it. To run the examples, you must clone or download this repository.

Running the server side example

npm run example:server

Running the client side example

npm run example:client

This example is implemented on ReactJS and it was built with Vite.

API

Server API

import { YSocketIO } from 'y-socket.io/dist/server'
configuration = {
  // Optionally, set here the authentication validation callback (by default server accepts all connections)
  // For example: if client sent a token or other data, you can get it from auth object of 
  //              socket.io handshake
  authenticate: undefined, // Example: (handshake) => handshake.auth.token === 'valid-token')
  // Optionally, enable LevelDB persistence by setting the directory where you want to store the database (by default the LevelDB persistence is disabled)
  levelPersistenceDir: undefined,
  // Enable/Disable garbage collection (by default the garbage collection is enabled)
  gcEnabled: true,
}

Client API

import { SocketIOProvider } from 'y-socket.io'
configuration = {
  // Enable/Disable garbage collection (by default the garbage collection is enabled)
  gcEnabled: true,
  // Enable/Disable auto connect when the instance is created (by default the auto connection is enabled). Set this to "false" if you want to connect manually using provider.connect()
  autoConnect = true,
  // Specify an existing Awareness instance - see https://github.com/yjs/y-protocols
  awareness = new AwarenessProtocol.Awareness(doc),
  // Specify a number of milliseconds greater than 0 to resynchronize the document (by default is -1)
  resyncInterval = -1,
  // Disable broadcast channel synchronization (by default the broadcast channel synchronization is enabled)
  disableBc = false,
  // Specify the authentication data to send to the server on handshake
  auth = {} // Example: { token: 'valid-token' }
}

👦 Author

Iván Topp

🤝 Contributing

Contributions, issues and feature requests are welcome!

Show your support

Give a ⭐️ if this project helped you!

📝 License

Copyright © 2022 Iván Topp. This project is MIT licensed.


This README was generated with ❤️ by readme-md-generator