Skip to content

Commit bf7a177

Browse files
YJS: revert editor_id column
1 parent 86f4bf0 commit bf7a177

File tree

6 files changed

+24
-24
lines changed

6 files changed

+24
-24
lines changed

demos/yjs-react-supabase-text-collab/CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
- Added a local development option with local Supabase and PowerSync services.
66
- Updated Sync rules to use client parameters. Each client now only syncs `document` and `document_updates` for the document being edited.
77
- Updated `PowerSyncYjsProvider` to use an incremental watched query for `document_updates`.
8-
- Added a `editor_id` column to the `document_updates` table. This tracks which editor created the update and avoids reapplying updates in the source editor.
98
- The incremental watched query now applies updates from external editors.
109

1110
## 0.1.16

demos/yjs-react-supabase-text-collab/src/library/powersync/AppSchema.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ const document_updates = new Table(
99
{
1010
document_id: column.text,
1111
created_at: column.text,
12-
update_b64: column.text,
13-
// Store an id of whom the update was created by.
14-
// This is only used to not reapply updates which were created by the local editor.
15-
editor_id: column.text
12+
update_b64: column.text
1613
},
1714
{ indexes: { by_document: ['document_id'] } }
1815
);

demos/yjs-react-supabase-text-collab/src/library/powersync/PowerSyncYjsProvider.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as Y from 'yjs';
33
import { b64ToUint8Array, Uint8ArrayTob64 } from '@/library/binary-utils';
44
import { AbstractPowerSyncDatabase } from '@powersync/web';
55
import { ObservableV2 } from 'lib0/observable';
6-
import { v4 as uuidv4 } from 'uuid';
76
import { DocumentUpdates } from './AppSchema';
87

98
export interface PowerSyncYjsEvents {
@@ -26,8 +25,6 @@ export interface PowerSyncYjsEvents {
2625
*/
2726
export class PowerSyncYjsProvider extends ObservableV2<PowerSyncYjsEvents> {
2827
private abortController = new AbortController();
29-
// This ID is updated on every new instance of the provider.
30-
private id = uuidv4();
3128

3229
constructor(
3330
public readonly doc: Y.Doc,
@@ -49,9 +46,8 @@ export class PowerSyncYjsProvider extends ObservableV2<PowerSyncYjsEvents> {
4946
document_updates
5047
WHERE
5148
document_id = ?
52-
AND editor_id != ?
5349
`,
54-
parameters: [documentId, this.id]
50+
parameters: [documentId]
5551
})
5652
.differentialWatch();
5753

@@ -68,11 +64,18 @@ export class PowerSyncYjsProvider extends ObservableV2<PowerSyncYjsEvents> {
6864
this.destroy = this.destroy.bind(this);
6965

7066
let synced = false;
71-
67+
const origin = this;
7268
updateQuery.registerListener({
7369
onDiff: async (diff) => {
7470
for (const added of diff.added) {
75-
Y.applyUpdateV2(doc, b64ToUint8Array(added.update_b64));
71+
/**
72+
* Local document updates get stored to the database and synced.
73+
*
74+
* These updates here originate from syncing remote updates.
75+
* Applying these updates to YJS should not result in the `storeUpdate`
76+
* handler creating a new `document_update` record. We mark the origin
77+
*/
78+
Y.applyUpdateV2(doc, b64ToUint8Array(added.update_b64), origin);
7679
}
7780
if (!synced) {
7881
synced = true;
@@ -89,15 +92,19 @@ export class PowerSyncYjsProvider extends ObservableV2<PowerSyncYjsEvents> {
8992
}
9093

9194
private async _storeUpdate(update: Uint8Array, origin: any) {
92-
// update originated from elsewhere - save to the database
95+
if (origin === this) {
96+
// update originated from the database / PowerSync - ignore
97+
return;
98+
}
99+
93100
await this.db.execute(
94101
/* sql */ `
95102
INSERT INTO
96-
document_updates (id, document_id, update_b64, editor_id)
103+
document_updates (id, document_id, update_b64)
97104
VALUES
98-
(uuid (), ?, ?, ?)
105+
(uuid (), ?, ?)
99106
`,
100-
[this.documentId, Uint8ArrayTob64(update), this.id]
107+
[this.documentId, Uint8ArrayTob64(update)]
101108
);
102109
}
103110

demos/yjs-react-supabase-text-collab/supabase/functions/merge-document-updates/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ Deno.serve(async (req) => {
5555
// insert the new merged update as new single update for the document
5656
const supabaseInsert = await supabase.from('document_updates').insert({
5757
document_id: document_id,
58-
update_data: Uint8ArrayToHex(docState),
59-
editor_id: 'merged_update'
58+
update_data: Uint8ArrayToHex(docState)
6059
});
6160
if (supabaseInsert.error) {
6261
throw new Error(supabaseInsert.error);

demos/yjs-react-supabase-text-collab/supabase/migrations/20250618064101_configure_powersync.sql

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ CREATE TABLE document_updates(
1010
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
1111
created_at timestamptz DEFAULT now(),
1212
document_id UUID,
13-
update_data BYTEA,
14-
editor_id UUID
13+
update_data BYTEA
1514
);
1615

1716

@@ -28,12 +27,11 @@ $$ LANGUAGE SQL;
2827
CREATE OR REPLACE FUNCTION insert_document_updates(batch TEXT)
2928
RETURNS VOID AS $$
3029
BEGIN
31-
INSERT INTO document_updates (id, document_id, update_data, editor_id)
30+
INSERT INTO document_updates (id, document_id, update_data)
3231
SELECT
3332
(elem->>'id')::UUID,
3433
(elem->>'document_id')::UUID,
35-
decode(elem->>'update_b64', 'base64'),
36-
(elem->>'editor_id')::UUID
34+
decode(elem->>'update_b64', 'base64')
3735
FROM json_array_elements(batch::json) AS elem
3836
ON CONFLICT (id) DO NOTHING;
3937
END;

demos/yjs-react-supabase-text-collab/sync-rules.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ bucket_definitions:
88
parameters: SELECT (request.parameters() ->> 'document_id') as document_id
99
data:
1010
- SELECT * FROM documents WHERE id = bucket.document_id
11-
- SELECT id, document_id, base64(update_data) as update_b64, editor_id FROM document_updates WHERE document_id = bucket.document_id
11+
- SELECT id, document_id, base64(update_data) as update_b64 FROM document_updates WHERE document_id = bucket.document_id

0 commit comments

Comments
 (0)