Created
February 19, 2025 14:46
-
-
Save mmacphail/fadf7dc008746f03672b9d108782e666 to your computer and use it in GitHub Desktop.
Y.JS learning spike
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { describe, it, expect, beforeEach } from 'vitest'; | |
| import * as Y from 'yjs'; | |
| import { encodeStateAsUpdate, applyUpdate } from 'yjs'; | |
| describe('Y.js Learning Spike', () => { | |
| let doc; | |
| let text; | |
| let doc2; | |
| let text2; | |
| let update; | |
| beforeEach(() => { | |
| doc = new Y.Doc(); | |
| text = doc.getText('text'); | |
| doc2 = new Y.Doc(); | |
| text2 = doc2.getText('text'); | |
| text.insert(0, 'Hello'); | |
| text2.insert(0, 'World'); | |
| update = encodeStateAsUpdate(doc); | |
| }); | |
| it('should apply updates', () => { | |
| const doc = new Y.Doc(); | |
| const text = doc.getText('text'); | |
| text.insert(0, 'Hello'); | |
| expect(text.toString()).toBe('Hello'); | |
| const update = encodeStateAsUpdate(doc); | |
| const doc2 = new Y.Doc(); | |
| const text2 = doc2.getText('text'); | |
| text2.insert(0, 'World'); | |
| expect(text2.toString()).toBe('World'); | |
| applyUpdate(doc2, update); | |
| expect(text2.toString()).toContain('Hello'); | |
| expect(text2.toString()).toContain('World'); | |
| }); | |
| it('should trigger observers when updating', () => { | |
| let changed = false; | |
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | |
| text2.observe((event) => { | |
| changed = true; | |
| }); | |
| applyUpdate(doc2, update); | |
| expect(changed).toBe(true); | |
| }); | |
| it('should allow rolling back changes using UndoManager', () => { | |
| const undoManager = new Y.UndoManager(text); | |
| expect(text.toString()).toBe('Hello'); | |
| text.insert(5, ' World'); | |
| expect(text.toString()).toBe('Hello World'); | |
| undoManager.undo(); | |
| expect(text.toString()).toBe('Hello'); | |
| undoManager.redo(); | |
| expect(text.toString()).toBe('Hello World'); | |
| }); | |
| it('should handle transactions as atomic operations', () => { | |
| let observerCallCount = 0; | |
| // Set up observer to count changes | |
| text.observe(() => { | |
| observerCallCount++; | |
| }); | |
| // Multiple operations without transaction - will trigger observer multiple times | |
| text.insert(0, 'Hello'); | |
| text.insert(5, ' '); | |
| text.insert(6, 'World'); | |
| expect(observerCallCount).toBe(3); | |
| // Reset counter | |
| observerCallCount = 0; | |
| // Multiple operations within a transaction - will trigger observer only once | |
| doc.transact(() => { | |
| text.delete(0, text.length); // Clear text | |
| text.insert(0, 'Hello'); | |
| text.insert(5, ' '); | |
| text.insert(6, 'World'); | |
| }); | |
| expect(observerCallCount).toBe(1); | |
| expect(text.toString()).toBe('Hello World'); | |
| }); | |
| }); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment