npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@styris-ame/y-engineio

v2.2.0

Published

Engine.IO provider for Yjs (Yjs v13 line)

Readme

@styris-ame/y-engineio :tophat:

Engine.IO Provider for Yjs

A port of y-websocket that syncs a Y.Doc over Engine.IO (the transport layer underneath Socket.IO) instead of a raw WebSocket. It keeps the same sync + awareness protocol and the same cross-tab BroadcastChannel sync.

Why Engine.IO? It negotiates a transport (HTTP long-polling → WebSocket → WebTransport) and transparently falls back when WebSockets are blocked by a proxy, which a raw WebSocket cannot do.

This is the v4 / main-branch port: it targets Yjs v14 (@y/y, @y/protocols) and includes the sync-status feature.

Yjs v13 vs v14

This 2.x line (dist-tag yjs14) targets Yjs v14 (@y/y, @y/protocols). For Yjs v13 (yjs, y-protocols, lib0@^0.2) install the 1.x line (dist-tag yjs13): npm i @styris-ame/y-engineio@yjs13 yjs.

Quick Start

npm i @styris-ame/y-engineio@yjs14 engine.io-client @y/y
import * as Y from '@y/y'
import { EngineIOProvider } from '@styris-ame/y-engineio'

const doc = new Y.Doc()
// note: serverUrl is just the origin — the room name is NOT part of the URL
const provider = new EngineIOProvider('http://localhost:1234', 'my-roomname', doc)

provider.on('status', event => {
  console.log(event.status) // "connecting" | "connected" | "disconnected"
})

How it differs from y-websocket

| | y-websocket | @styris-ame/y-engineio | |---|---|---| | transport | raw WebSocket | engine.io-client Socket (polling/ws/webtransport) | | URL | serverUrl/roomname?params | serverUrl only; params become engine.io query | | room selection | encoded in the URL path | sent as the room handshake query param (see below) | | socket field | provider.ws | provider.engine |

Everything else — the messageSync / messageAwareness / messageAuth / messageQueryAwareness protocol, exponential-backoff reconnect, the socketTimeout watchdog, sync / sync-status events, and cross-tab BroadcastChannel sync — is unchanged from y-websocket.

Wire protocol (for server authors)

Every frame is binary (engine.io binary message) and starts with a lib0-encoded varUint message type:

| type | const | direction | payload | |---|---|---|---| | 0 | messageSync | both | @y/protocols/sync message | | 1 | messageAwareness | both | varUint8Array awareness update | | 2 | messageAuth | server→client | @y/protocols/auth message | | 3 | messageQueryAwareness | both | (empty) |

Room handshake

Because engine.io has a single connection endpoint (no per-room URL), the client declares its room as the room handshake query parameter, alongside any user-supplied params. engine.io-client URL-encodes query values, so the room name needs no manual escaping.

The server reads room from the handshake query (e.g. engine.io's allowRequest middleware or socket.request) and binds the connection to that room before any frames are exchanged. Because it is available at handshake time, the server can reject an unknown or unauthorized room immediately instead of accepting the socket and waiting for a first frame. After the connection opens the client proceeds exactly like y-websocket: it sends sync step 1 and its local awareness state.

API

import { EngineIOProvider } from '@styris-ame/y-engineio'

new EngineIOProvider(serverUrl: string, room: string, ydoc: Y.Doc, opts?)

serverUrl is the engine.io server origin (e.g. http://localhost:1234). The following opts are supported:

{
  // connect immediately; set false to call provider.connect() yourself
  connect: true,
  // query-string params -> engine.io `query`
  params: {}, // Object<string,string>
  // forwarded verbatim to the engine.io-client Socket
  // (e.g. path, transports, withCredentials, extraHeaders, ...)
  engineOptions: {},
  // override the engine.io-client Socket constructor (e.g. for tests)
  EngineClass: Socket,
  // existing awareness instance
  awareness: new awarenessProtocol.Awareness(ydoc),
  // resend sync step 1 every N ms (-1 disables)
  resyncInterval: -1,
  // max backoff between reconnects (exponential)
  maxBackoffTime: 2500,
  // disable cross-tab BroadcastChannel sync
  disableBc: false,
  // close + reconnect if no message received for this long
  socketTimeout: /* ~1.5 * awareness outdatedTimeout */
}

Instance fields & events match y-websocket, except the ws-prefixed fields are renamed (connected, connecting, unsuccessfulReconnects, lastMessageReceived): connected, connecting, shouldConnect, bcconnected, synced, syncStatus, params, connect(), disconnect(), destroy(), and the status, sync, sync-status, connection-close, connection-error events. The live socket is exposed as provider.engine (an engine.io-client Socket) rather than provider.ws.

License

The MIT License — port of y-websocket © Kevin Jahns