Newby having problems with yjs/yrb/codemirror


I’m working with yjs on my college project, intending to use it on a collaborative editor for coding for schools, but I’m having some trouble making it work with a backend. As a background, I am mainly a backend Rails developer, though this is my first time using action cable for anything, for this project I have to use Angular (not my choice) so I’m trying to build a proof of concept before actually working on the real deal.

My problem is that even though I get no error messages, the editors do work collaboratively between tabs of the same browser, and I do see messages being sent and received between backend and frontend, I do not see the actual document from the backend in the frontend.

I’ll post the code below, but here’s a link to the repo:

// crdt_yjs_matefun/frontend/src/app/code-editor/code-editor.component.ts
import { Component } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'
import { OnInit } from '@angular/core';
import * as Y from "yjs";
import { WebsocketProvider } from "@y-rb/actioncable";
import CodeMirror from "codemirror";
import { CodeMirrorBinding } from 'y-codemirror'
import ActionCable from 'actioncable'

  selector: 'code-editor',
  templateUrl: './code-editor.component.html',
  styleUrls: ['./code-editor.component.scss']
export class CodeEditorComponent implements OnInit {

  constructor(private http: HttpClient) {

  ngOnInit() {
    const accessToken = localStorage.getItem('accessToken')
    const uid = localStorage.getItem('uid')
    const client = localStorage.getItem('client')

    const yDocument = new Y.Doc();
    const consumer = ActionCable.createConsumer(`ws://localhost:3000/cable?uid=${uid}&access-token=${accessToken}&client=${client}`);
    const provider = new WebsocketProvider(
    const yText = yDocument.getText('codemirror')

    const yUndoManager = new Y.UndoManager(yText)

    const editorContainer = document.createElement('div')
    editorContainer.setAttribute('id', 'editor')
    document.body.insertBefore(editorContainer, null)

    const editor = CodeMirror(editorContainer, {
      mode: 'javascript',
      lineNumbers: true,

    const binding = new CodeMirrorBinding(yText, editor, provider.awareness, { yUndoManager })

    // @ts-ignore
    //window.example = { provider, ydoc, yText, binding, Y }
# backend/app/channels/application_cable/document_channel.rb
require 'y-rb'

module ApplicationCable
  class DocumentChannel < ApplicationCable::Channel
    include Y::Actioncable::Sync

    def initialize(connection, identifier, params = nil)
      load { |id| load_doc 1 }

    def subscribed

    def receive(data)
      sync_to("document-1", data)

    def unsubscribed


    def load_doc(id)
      doc_content = Document.first.content
      ydoc =
      ytext = ydoc.get_text('mine')
      ytext << doc_content
      data = []
      data = ydoc.diff unless doc_content.nil?

Could anyone guide me to make this work, or hint at what could the problem be?