ueberdosis / hocuspocus

The CRDT Yjs WebSocket backend for conflict-free real-time collaboration in your app.
https://tiptap.dev/docs/hocuspocus/introduction
MIT License
1.19k stars 115 forks source link

backend onChange undefined #793

Closed wxfred closed 5 months ago

wxfred commented 5 months ago

Description I followed the example on https://tiptap.dev/docs/hocuspocus/getting-started

My backend

import { Server } from '@hocuspocus/server'

const server = Server.configure({
  port: 1234,

  async connected() {
    console.log('connections: ', server.getConnectionsCount());
  },
  async onChange(data) {
    console.log('document', data.document.toJSON());
    console.log('tasks', data.document.get('tasks').toJSON())
  },
})

server.listen()

My frontend (Vue)

import * as Y from "yjs";
import { HocuspocusProvider } from "@hocuspocus/provider";

// Connect it to the backend
const provider = new HocuspocusProvider({
  url: "ws://127.0.0.1:1234",
  name: "example-document",
});

// Define `tasks` as an Array
const tasks = provider.document.getArray("tasks");

// Listen for changes
tasks.observe(() => {
  console.log("tasks were modified", tasks.toJSON());
});

// Add a new task
tasks.push(["buy milk"]);

And the log from frontend tasks were modified ['buy milk']

But on the server side, the log is

connections:  1
document { tasks: undefined }
tasks undefined

Why tasks on backend is undefined? Is there anything I missed?

Environment?

Additional context Add any other context about the problem here.

wxfred commented 5 months ago

I tried this

...
import { TiptapTransformer } from '@hocuspocus/transformer'

...
async onChange(data) {
  const prosemirrorJSON = TiptapTransformer.fromYdoc(data.document);
  console.log(prosemirrorJSON)
},

crash came out

[onChange] item.toDelta is not a function
file:///xxxx/hocuspocus/node_modules/y-prosemirror/src/lib.js:331
      const delta = item.toDelta()
                         ^

TypeError: item.toDelta is not a function
    at serialize (file:///xxxx/hocuspocus/node_modules/y-prosemirror/src/lib.js:331:26)
    at Array.map (<anonymous>)
    at yXmlFragmentToProsemirrorJSON (file:///xxxx/hocuspocus/node_modules/y-prosemirror/src/lib.js:375:20)
    at yDocToProsemirrorJSON (file:///xxxx/hocuspocus/node_modules/y-prosemirror/src/lib.js:308:10)      
    at Prosemirror.fromYdoc (file:///xxxx/hocuspocus/node_modules/@hocuspocus/transformer/dist/hocuspocus-transformer.esm.js:2625:20)
    at Tiptap.fromYdoc (file:///xxxx/hocuspocus/node_modules/@hocuspocus/transformer/dist/hocuspocus-transformer.esm.js:2667:39)
    at Object.onChange (file:///xxxx/hocuspocus/index.js:14:47)
    at file:///xxxx/hocuspocus/node_modules/@hocuspocus/server/dist/hocuspocus-server.esm.js:2806:109    
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
wxfred commented 5 months ago

Sorry, I located my mistakes: On the backend, I used a get instead of getArray, and data.document.toJSON() is deprecated. console.log('tasks', data.document.**getArray**('tasks').toJSON()) // logs: tasks [ 'buy milk' ]