Background
Hello, I am learning web development. (I’m not a developer yet).
I decided to implement a collabolative editing document for the members of the reading club.
Since I am mainly learning Rails, I will use Rails for the backend.
Rails 7.1.3.4
ruby 3.3.0
I will use React for the frontend.
And I plan to use TipTap and Y.js as libraries.
"react": "^18.3.1",
"react-dom": "^18.3.1",
"@tiptap/extension-collaboration": "^2.5.7",
"@tiptap/pm": "^2.5.7",
"@tiptap/react": "^2.5.7",
"@tiptap/starter-kit": "^2.5.7",
"yjs": "^13.6.18"
I tried to follow the official documentation and successfully implemented a collaborative editing document.
However, the free version limits the number of simultaneous connections to 10, which I thought was insufficient for my service.
Therefore, taking advantage of the fact that the backend is Rails, I am thinking of using ActionCable for WebSocket connection.
Problem
I am going to use y-crdt/yrb-actioncable for easier implementation.
But I followed the README and the app doesn’t work at all.
I would like to paste the code below. Please give me any advice you may have.
In the first place, I may be doing something misguided because of my limited understanding of ActionCable and Prosemirror. Please forgive me.
# config/cable.yml
development:
adapter: async
url: redis://localhost:6379/1
channel_prefix: myapp_development
test:
adapter: test
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: rindokukai_note_sample_production
# app/channels/note_channel.rb
class NoteChannel < ApplicationCable::Channel
include Y::Actioncable::Sync
def subscribed
sync_for(session)
end
def receive(data)
sync_to(session, message)
end
end
// app/javascript/channels/note_channel.js
// I have no idea...sorry...
import consumer from "./consumer"
consumer.subscriptions.create("NoteChannel", {
connected() {
// Called when the subscription is ready for use on the server
},
disconnected() {
// Called when the subscription has been terminated by the server
},
received(data) {
// Called when there's incoming data on the websocket for this channel
}
});
// app/javascript/components/TipTap/TipTapEditors.jsx
import React from 'react';
import { useEditor, EditorContent } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import * as Y from 'yjs'
import Collaboration from '@tiptap/extension-collaboration'
import {WebsocketProvider} from "@y-rb/actioncable";
import { createConsumer } from "@rails/actioncable";
import CollaborationCursor from '@tiptap/extension-collaboration-cursor'
export const TipTapContent = ({state, updateNote}) => {
const doc = new Y.Doc();
const consumer = createConsumer();
// followed READ ME
const provider = new WebsocketProvider(
doc,
consumer,
"NoteChannel",
{id: "1"}
);
const editor = useEditor(
{
extensions: [
StarterKit,
Collaboration.configure({
document: doc,
}),
CollaborationCursor.configure({
provider,
user: {name: "Hannes", color: "#ff0000"}
})
],
content: state.content,
onUpdate({editor}){
const newContent = editor.getText();
updateNote("content", newContent);
},
}
)
return(
<>
<EditorContent editor={editor} />
</>
)
}
Finally
Thank you for looking at my poor English.
I thought about implementing it with TipTap and Y.js this time, but if there is a less expensive way, I will do it there. (The backend is in Rails).
Please mention any codes you need. I will paste it right away.
I am in a different industry now, but I am trying to make this application to change jobs.
Any help you can provide would be greatly appreciated.
Thank you.