Skip to content

Commit

Permalink
fix: broadcast channel names are not unique per document
Browse files Browse the repository at this point in the history
  • Loading branch information
eliias committed May 8, 2023
1 parent 46c89b8 commit 7ca8093
Show file tree
Hide file tree
Showing 7 changed files with 524 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def doc
private

def session
@session ||= Session.new(params[:path])
@session ||= Session.new(params[:id])
end

def load_doc(id)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {Controller} from "@hotwired/stimulus";
import {Editor} from "@tiptap/core";
import {Collaboration} from "@tiptap/extension-collaboration";
import {CollaborationCursor} from "@tiptap/extension-collaboration-cursor";
import {StarterKit} from "@tiptap/starter-kit";
import {WebsocketProvider} from "@y-rb/actioncable";
import {fromBase64} from "lib0/buffer";
import {applyUpdate, Doc} from "yjs";
import { Controller } from "@hotwired/stimulus";
import { Editor } from "@tiptap/core";
import { Collaboration } from "@tiptap/extension-collaboration";
import { CollaborationCursor } from "@tiptap/extension-collaboration-cursor";
import { StarterKit } from "@tiptap/starter-kit";
import { WebsocketProvider } from "@y-rb/actioncable";
import { fromBase64 } from "lib0/buffer";
import { applyUpdate, Doc } from "yjs";

import {consumer} from "../channels";
import { consumer } from "../channels";

export default class extends Controller<HTMLFormElement> {
static values = {
Expand All @@ -25,11 +25,19 @@ export default class extends Controller<HTMLFormElement> {
applyUpdate(document, initialState);
}

const params = new URLSearchParams(window.location.search);
const id = params.get("id");
if (id == null) {
return alert("Provide an `?id=doc-id` query param.");
}

const provider = new WebsocketProvider(
document,
consumer,
"SyncChannel",
{path: "issues/1"}
{
id
}
);

new Editor({
Expand All @@ -48,17 +56,12 @@ export default class extends Controller<HTMLFormElement> {
color: this.getRandomColor()
}
})
],
]
});
}

getRandomColor() {
const colors = [
"#ff901f",
"#ff2975",
"#f222ff",
"#8c1eff",
];
const colors = ["#ff901f", "#ff2975", "#f222ff", "#8c1eff"];

const selectedIndex = Math.floor(Math.random() * (colors.length - 1));
return colors[selectedIndex];
Expand Down
1 change: 1 addition & 0 deletions examples/collaborative-text-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"@tiptap/core": "^2.0.1",
"@tiptap/extension-collaboration": "^2.0.0-beta.209",
"@tiptap/extension-collaboration-cursor": "^2.0.3",
"@tiptap/pm": "^2.0.3",
"@tiptap/starter-kit": "^2.0.2",
"@y-rb/actioncable": "*",
"esbuild": "^0.17.10",
Expand Down
6 changes: 6 additions & 0 deletions packages/yrb-actioncable/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# yrb-actioncable

## 0.2.0

### Minor Changes

- Fixes non-unique broadcast channel names.

## 0.1.5

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/yrb-actioncable/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.5",
"version": "0.2.0",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down
20 changes: 12 additions & 8 deletions packages/yrb-actioncable/src/websocket-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export class WebsocketProvider {
readonly params: Record<string, string>;
readonly doc: Doc;
readonly channelName: string;
readonly bcChannelName: string;
readonly awareness: Awareness;
bcconnected: boolean;
private readonly disableBc: boolean;
Expand All @@ -123,6 +124,9 @@ export class WebsocketProvider {
) {
this.consumer = consumer;
this.channelName = channel;
this.bcChannelName = `${channel}_${Object.entries(params)
.map((k, v) => `${k}-${v}`)
.join('_')}`;
this.params = params;
this.doc = doc;
this.awareness = awareness;
Expand All @@ -147,7 +151,7 @@ export class WebsocketProvider {
if (origin !== this) {
const encoder = this.process(new Uint8Array(data), false);
if (encodingLength(encoder) > 1) {
publish(this.channelName, toUint8Array(encoder), this);
publish(this.bcChannelName, toUint8Array(encoder), this);
}
}
};
Expand Down Expand Up @@ -210,7 +214,7 @@ export class WebsocketProvider {
this.channel?.send({ update });

if (this.bcconnected) {
publish(this.channelName, buffer, this);
publish(this.bcChannelName, buffer, this);
}
}

Expand Down Expand Up @@ -281,7 +285,7 @@ export class WebsocketProvider {
}

if (!this.bcconnected) {
subscribe(this.channelName, this.bcSubscriber);
subscribe(this.bcChannelName, this.bcSubscriber);
this.bcconnected = true;
}

Expand All @@ -290,18 +294,18 @@ export class WebsocketProvider {
const encoderSync = createEncoder();
writeVarUint(encoderSync, MessageType.Sync);
writeSyncStep1(encoderSync, this.doc);
publish(this.channelName, toUint8Array(encoderSync), this);
publish(this.bcChannelName, toUint8Array(encoderSync), this);

// broadcast local state
const encoderState = createEncoder();
writeVarUint(encoderState, MessageType.Sync);
writeSyncStep2(encoderState, this.doc);
publish(this.channelName, toUint8Array(encoderState), this);
publish(this.bcChannelName, toUint8Array(encoderState), this);

// write queryAwareness
const encoderAwarenessQuery = createEncoder();
writeVarUint(encoderAwarenessQuery, MessageType.QueryAwareness);
publish(this.channelName, toUint8Array(encoderAwarenessQuery), this);
publish(this.bcChannelName, toUint8Array(encoderAwarenessQuery), this);

// broadcast local awareness state
const encoderAwarenessState = createEncoder();
Expand All @@ -310,7 +314,7 @@ export class WebsocketProvider {
encoderAwarenessState,
encodeAwarenessUpdate(this.awareness, [this.doc.clientID])
);
publish(this.channelName, toUint8Array(encoderAwarenessState), this);
publish(this.bcChannelName, toUint8Array(encoderAwarenessState), this);
}

private disconnectBc() {
Expand All @@ -323,7 +327,7 @@ export class WebsocketProvider {
);
this.send(toUint8Array(encoder));
if (this.bcconnected) {
unsubscribe(this.channelName, this.bcSubscriber);
unsubscribe(this.bcChannelName, this.bcSubscriber);
this.bcconnected = false;
}
}
Expand Down
Loading

0 comments on commit 7ca8093

Please sign in to comment.