hocuspocus icon indicating copy to clipboard operation
hocuspocus copied to clipboard

WebSocket compatibility issue with Deno runtime - missing .on/.off/.once methods

Open maamoon95 opened this issue 10 months ago • 1 comments

Description Hocuspocus server's handleConnection method expects WebSocket objects to have Node.js-style event emitter methods (.on, .off, .once), but when using Hocuspocus with Deno's WebSocket implementation (particularly through frameworks like Hono), these methods are not available. Deno's WebSocket follows the standard Web API and only provides addEventListener and removeEventListener methods, causing compatibility issues.

Steps to reproduce the bug

  1. Set up a Deno project with Hocuspocus server version 3.1.3
  2. Use Hono framework with upgradeWebSocket from 'hono/deno'
  3. Attempt to call hocuspocus.handleConnection(ws.raw, request) where ws.raw is the Deno WebSocket
  4. See error that .on, .off, and .once methods are not functions

Code example:

import { upgradeWebSocket } from 'hono/deno'
import { Hocuspocus } from '@hocuspocus/server';

const hocuspocus = new Hocuspocus({
  name: 'collaboration'
});

export const websocketHandler = upgradeWebSocket((ctx) => {
  return {
    onOpen(_evt, ws) {
      // This fails because ws.raw doesn't have .on, .off, .once methods
      hocuspocus.handleConnection(ws.raw, ctx.req.raw);
    }
  }
});

Current workaround:

// Manual polyfill needed
ws.raw.on = ws.raw.addEventListener.bind(ws.raw);
ws.raw.off = ws.raw.removeEventListener.bind(ws.raw);
ws.raw.once = (event: string, listener: (...args: any[]) => void) => {
  const wrappedListener = (...args: any[]) => {
    listener(...args);
    ws.raw.removeEventListener(event, wrappedListener);
  };
  ws.raw.addEventListener(event, wrappedListener);
};

Expected behavior Hocuspocus should handle WebSocket objects that follow the standard Web API (using addEventListener/removeEventListener) in addition to Node.js-style event emitters, or provide an adapter/wrapper to make it compatible with different WebSocket implementations.

Environment

  • Operating system: Windows 11
  • Runtime: Deno 2.x
  • Framework: Hono with 'hono/deno' WebSocket adapter
  • Hocuspocus version: 3.1.3

Additional context This issue affects Deno users who want to use Hocuspocus for collaborative editing. The problem stems from the difference between:

  1. Node.js WebSocket libraries (like 'ws') that provide .on(), .off(), .once() methods
  2. Deno/Web API WebSocket that follows the standard and only provides addEventListener() and removeEventListener()

A potential solution would be for Hocuspocus to detect the WebSocket type and either:

  • Add internal polyfills for the missing methods
  • Use a wrapper that normalizes the interface
  • Accept both Node.js-style and Web API-style WebSocket objects

This would make Hocuspocus more compatible with modern runtime environments like Deno, Bun, and browser environments that follow Web API standards.

maamoon95 avatar Jun 10 '25 19:06 maamoon95

Same here 👍

luisfagottani avatar Jun 29 '25 22:06 luisfagottani