Environment
quill-table-up: 2.1.9
quill: 2.x
Collaborative backend: Yjs + y-quill binding
History module configuration
history: {
delay: 200,
userOnly: true
}
userOnly: true means remote changes are not recorded into the undo stack, but Quill's History module still calls transform() against each incoming remote delta to adjust the positions of existing undo stack entries.
Steps to Reproduce
User A and User B open the same document collaboratively
User A inserts a 3×3 table (rows: r1/r2/r3, cols: c1/c2/c3)
User A deletes row 2
User B deletes column 2
User A presses Ctrl+Z to undo the row deletion
Expected
Row 2 is restored with 2 cells, matching the current 2-column table structure.
Actual
The table layout corrupts. The restored row contains a cell whose colId attribute is c2, which no longer exists in the table's column list.
Analysis
When User A deletes row 2, the History module records an undo delta containing the 3 cells of row 2, each carrying their original colId attributes (c1, c2, c3).
When User B's delete-column operation arrives as a remote delta, History.transform() is called to adjust the existing undo stack entries. The remote delta carries no information about which colId was deleted — it only encodes byte-position offsets.
transformStack() adjusts the undo stack using Delta.transform(), which correctly shifts positional offsets but cannot update or remove the colId attribute inside the insert ops of the undo delta, because the remote delta carries no column identity information.
As a result, when User A's undo is applied, the restored row inserts a cell with colId = c2 into a table whose column list is now [c1, c3]. The table renderer encounters a colId with no corresponding column definition, causing the layout to corrupt.
I'm not sure if this is a known limitation or something that could be addressed in quill-table-up. Any insight into whether the delete-column operation could carry column identity information in its delta, or whether there's a recommended way to handle this in collaborative scenarios, would be greatly appreciated.
Thank you so much!🙏
Environment
quill-table-up: 2.1.9
quill: 2.x
Collaborative backend: Yjs + y-quill binding
History module configuration
userOnly: true means remote changes are not recorded into the undo stack, but Quill's History module still calls transform() against each incoming remote delta to adjust the positions of existing undo stack entries.
Steps to Reproduce
User A and User B open the same document collaboratively
User A inserts a 3×3 table (rows: r1/r2/r3, cols: c1/c2/c3)
User A deletes row 2
User B deletes column 2
User A presses Ctrl+Z to undo the row deletion
Expected
Row 2 is restored with 2 cells, matching the current 2-column table structure.
Actual
The table layout corrupts. The restored row contains a cell whose colId attribute is c2, which no longer exists in the table's column list.
Analysis
When User A deletes row 2, the History module records an undo delta containing the 3 cells of row 2, each carrying their original colId attributes (c1, c2, c3).
When User B's delete-column operation arrives as a remote delta, History.transform() is called to adjust the existing undo stack entries. The remote delta carries no information about which colId was deleted — it only encodes byte-position offsets.
transformStack() adjusts the undo stack using Delta.transform(), which correctly shifts positional offsets but cannot update or remove the colId attribute inside the insert ops of the undo delta, because the remote delta carries no column identity information.
As a result, when User A's undo is applied, the restored row inserts a cell with colId = c2 into a table whose column list is now [c1, c3]. The table renderer encounters a colId with no corresponding column definition, causing the layout to corrupt.
I'm not sure if this is a known limitation or something that could be addressed in quill-table-up. Any insight into whether the delete-column operation could carry column identity information in its delta, or whether there's a recommended way to handle this in collaborative scenarios, would be greatly appreciated.
Thank you so much!🙏